﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;


namespace CCImage
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            Console.WriteLine("这是一个图像处理测试程序");
            InitializeComponent();
            myTimer = new HiPerfTimer();

            //grb
            redCom = 0;
            greenCom = 0;
            blueCom = 0;
            hueCom = 0;
            satCom = 0;
            intCom = 0;
            tempArray = null;
        }

        private void 打开图像ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Console.WriteLine("打开图像");
            OpenFileDialog opnDlg = new OpenFileDialog();
            opnDlg.Filter = "所有图像文件 | *.bmp; *.pcx; *.png; *.jpg; *.gif;" +
                "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf|" +
                "位图( *.bmp; *.jpg; *.png;...) | *.bmp; *.pcx; *.png; *.jpg; *.gif; *.tif; *.ico|" +
                "矢量图( *.wmf; *.eps; *.emf;...) | *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf";
            opnDlg.Title = "打开图像文件";
            opnDlg.ShowHelp = true;
            if (opnDlg.ShowDialog() == DialogResult.OK)
            {
                curFileName = opnDlg.FileName;
                try
                {
                    Console.WriteLine(curFileName);
                    curBitmap = (Bitmap)Image.FromFile(curFileName);
                    this.Text = "CCImage : " + curFileName; 
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }
            }
            Invalidate();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (curBitmap != null)
            {
                //g.DrawImage(curBitmap, 20, 20, curBitmap.Width, curBitmap.Height);
                pictureBox1.Image = curBitmap;
            }
        }

        private void 保存图像ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (curBitmap == null)
            {
                return;
            }
            SaveFileDialog saveDlg = new SaveFileDialog();
            saveDlg.Title = "保存为";
            saveDlg.OverwritePrompt = true;
            saveDlg.Filter =
                "BMP文件 (*.bmp) | *.bmp|" +
                "Gif文件 (*.gif) | *.gif|" +
                "JPEG文件 (*.jpg) | *.jpg|" +
                "PNG文件 (*.png) | *.png";
            saveDlg.ShowHelp = true;
            if (saveDlg.ShowDialog() == DialogResult.OK)
            {
                string fileName = saveDlg.FileName;
                string strFilExtn = fileName.Remove(0, fileName.Length - 3);
                switch (strFilExtn)
                {
                    case "bmp":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Bmp);
                        break;
                    case "jpg":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                        break;
                    case "gif":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Gif);
                        break;
                    case "tif":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Tiff);
                        break;
                    case "png":
                        curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
                        break;
                    default:
                        break;
                }
            }
        }

        private void 关闭图像ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void 提取像素法ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                myTimer.ClearTimer();
                myTimer.Start();
                Color curColor;
                int ret;
                for (int i = 0; i < curBitmap.Width; i++)
                {
                    for (int j = 0; j < curBitmap.Height; j++)
                    {
                        curColor = curBitmap.GetPixel(i, j);
                        ret = (int)(curColor.R * 0.299 + curColor.G * 0.587 + curColor.B * 0.114);
                        curBitmap.SetPixel(i, j, Color.FromArgb(ret, ret, ret));
                    }
                }
                myTimer.Stop();
                toolStripStatusLabel1.Text = "运行时间：" + myTimer.Duration.ToString("####.##") + " 毫秒";
                Invalidate();
            }
        }

        private void 内存法ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                myTimer.ClearTimer();
                myTimer.Start();
                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                    //curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                IntPtr ptr = bmpData.Scan0;
                int bytes = curBitmap.Width * curBitmap.Height * 3;
                byte[] rgbValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
                double colorTemp = 0;
                for (int i = 0; i < rgbValues.Length; i += 3)
                {
                    colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114;
                    rgbValues[i] = rgbValues[i + 1] = rgbValues[i + 2] = (byte)colorTemp;
                }
                System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
                curBitmap.UnlockBits(bmpData);
                myTimer.Stop();
                toolStripStatusLabel1.Text = "运行时间：" + myTimer.Duration.ToString("####.##") + " 毫秒";
                Invalidate();
            }
        }

        private void 指针法ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                myTimer.ClearTimer();
                myTimer.Start();
                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                byte temp = 0;
                unsafe
                {
                    byte* ptr = (byte*)(bmpData.Scan0);
                    for (int i = 0; i < bmpData.Height; i++)
                    {
                        for (int j = 0; j < bmpData.Width; j++)
                        {
                            temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
                            ptr[0] = ptr[1] = ptr[2] = temp;
                            ptr += 3;
                        }
                        ptr += bmpData.Stride - bmpData.Width * 3;
                    }
                }
                curBitmap.UnlockBits(bmpData);
                myTimer.Stop();
                toolStripStatusLabel1.Text = "运行时间：" + myTimer.Duration.ToString("####.##") + " 毫秒";
                Invalidate();
            }
        }

        private void 绘制直方图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                histForm histoGram = new histForm(curBitmap);
                histoGram.ShowDialog();
                histoGram.Close();
            }
        }

        private void 线性点运算ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                linearPOForm linearForm = new linearPOForm();

                if (linearForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                    int temp = 0;
                    double a = Convert.ToDouble(linearForm.GetScaling);
                    double b = Convert.ToDouble(linearForm.GetOffset);
                    for (int i = 0; i < bytes; i++)
                    {
                        temp = (int)(a * grayValues[i] + b + 0.5);

                        if (temp > 255)
                        {
                            grayValues[i] = 255;
                        }
                        else if (temp < 0)
                        {
                            grayValues[i] = 0;
                        }
                        else
                            grayValues[i] = (byte)temp;
                    }
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                linearForm.Close();
                Invalidate();
            }
        }

        private void stretch_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {

                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                IntPtr ptr = bmpData.Scan0;
                int bytes = curBitmap.Width * curBitmap.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                byte a = 255, b = 0;
                double p;

                for (int i = 0; i < bytes; i++)
                {
                    if (a > grayValues[i])
                    {
                        a = grayValues[i];
                    }
                    if (b < grayValues[i])
                    {
                        b = grayValues[i];
                    }
                }
                p = 255.0 / (b - a);

                for (int i = 0; i < bytes; i++)
                {
                    grayValues[i] = (byte)(p * (grayValues[i] - a) + 0.5);
                }

                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curBitmap.UnlockBits(bmpData);

                Invalidate();
            }
        }

        private void equalization_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                IntPtr ptr = bmpData.Scan0;
                int bytes = curBitmap.Width * curBitmap.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                byte temp;
                int[] countPixel = new int[256];
                int[] tempArray = new int[256];
                //Array.Clear(tempArray, 0, 256);
                byte[] pixelMap = new byte[256];
                for (int i = 0; i < bytes; i++)
                {
                    temp = grayValues[i];
                    countPixel[temp]++;
                }

                for (int i = 0; i < 256; i++)
                {
                    if (i != 0)
                    {
                        tempArray[i] = tempArray[i - 1] + countPixel[i];
                    }
                    else
                    {
                        tempArray[0] = countPixel[0];
                    }

                    pixelMap[i] = (byte)(255.0 * tempArray[i] / bytes + 0.5);
                }

                for (int i = 0; i < bytes; i++)
                {
                    temp = grayValues[i];
                    grayValues[i] = pixelMap[temp];
                }
                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curBitmap.UnlockBits(bmpData);

                Invalidate();
            }
        }

        private void shaping_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                shapingForm sForm = new shapingForm();

                if (sForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte temp = 0;
                    double[] PPixel = new double[256];
                    double[] QPixel = new double[256];
                    int[] qPixel = new int[256];
                    int[] tempArray = new int[256];
                    for (int i = 0; i < grayValues.Length; i++)
                    {
                        temp = grayValues[i];
                        qPixel[temp]++;
                    }

                    for (int i = 0; i < 256; i++)
                    {
                        if (i != 0)
                        {
                            tempArray[i] = tempArray[i - 1] + qPixel[i];
                        }
                        else
                        {
                            tempArray[0] = qPixel[0];
                        }

                        QPixel[i] = (double)tempArray[i] / (double)bytes;
                    }

                    PPixel = sForm.ApplicationP;

                    double diffA, diffB;
                    byte k = 0;
                    byte[] mapPixel = new byte[256];
                    for (int i = 0; i < 256; i++)
                    {
                        diffB = 1;
                        for (int j = k; j < 256; j++)
                        {
                            diffA = Math.Abs(QPixel[i] - PPixel[j]);
                            if (diffA - diffB < 1.0E-08)
                            {
                                diffB = diffA;
                                k = (byte)j;
                            }
                            else
                            {
                                k = (byte)(j - 1);
                                break;
                            }
                        }
                        if (k == 255)
                        {
                            for (int l = i; l < 256; l++)
                            {
                                mapPixel[l] = k;

                            }
                            break;
                        }
                        mapPixel[i] = k;
                    }

                    for (int i = 0; i < bytes; i++)
                    {
                        temp = grayValues[i];
                        grayValues[i] = mapPixel[temp];
                    }


                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }
                Invalidate();
            }
        }

        //2018-02-02 16:58:29
        private void translation_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                translation traForm = new translation();
                if (traForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                        //curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    int x = Convert.ToInt32(traForm.GetXOffset);
                    int y = Convert.ToInt32(traForm.GetYOffset);

                    byte[] tempArray = new byte[bytes];
                    //Array.Clear(tempArray, 0, bytes);
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = 255;
                    }

                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        if ((i + y) < curBitmap.Height && (i + y) > 0)
                        {

                            for (int j = 0; j < curBitmap.Width; j++)
                            {
                                if ((j + x) < curBitmap.Width && (j + x) > 0)
                                {
                                    tempArray[(j + x) + (i + y) * curBitmap.Width] = grayValues[j + i * curBitmap.Width];
                                }
                            }
                        }
                    }

                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void mirror_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                mirror mirForm = new mirror();
                if (mirForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    int halfWidth = curBitmap.Width / 2;
                    int halfHeight = curBitmap.Height / 2;
                    byte temp;

                    if (mirForm.GetMirror)
                    {
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < halfWidth; j++)
                            {
                                temp = grayValues[i * curBitmap.Width + j];
                                grayValues[i * curBitmap.Width + j] = grayValues[(i + 1) * curBitmap.Width - 1 - j];
                                grayValues[(i + 1) * curBitmap.Width - 1 - j] = temp;
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < curBitmap.Width; i++)
                        {
                            for (int j = 0; j < halfHeight; j++)
                            {
                                temp = grayValues[j * curBitmap.Width + i];
                                grayValues[j * curBitmap.Height + i] = grayValues[(curBitmap.Height - j - 1) * curBitmap.Width + i];
                                grayValues[(curBitmap.Height - j - 1) * curBitmap.Width + i] = temp;
                            }
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void zoom_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                zoom zoomForm = new zoom();
                if (zoomForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    double x = Convert.ToDouble(zoomForm.GetXZoom);
                    double y = Convert.ToDouble(zoomForm.GetYZoom);

                    int halfWidth = (int)(curBitmap.Width / 2);
                    int halfHeight = (int)(curBitmap.Height / 2);

                    int xz = 0;
                    int yz = 0;
                    int tempWidth = 0;
                    int tempHeight = 0;

                    byte[] tempArray = new byte[bytes];

                    if (zoomForm.GetNearOrBil == true)
                    {
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < curBitmap.Width; j++)
                            {
                                tempHeight = i - halfHeight;
                                tempWidth = j - halfWidth;
                                if (tempWidth > 0)
                                {
                                    xz = (int)(tempWidth / x + 0.5);
                                }
                                else
                                {
                                    xz = (int)(tempWidth / x - 0.5);
                                }
                                if (tempHeight > 0)
                                {
                                    yz = (int)(tempHeight / y + 0.5);
                                }
                                else
                                {
                                    yz = (int)(tempHeight / y - 0.5);
                                }

                                tempWidth = xz + halfWidth;
                                tempHeight = yz + halfHeight;
                                if (tempWidth < 0 || tempWidth >= curBitmap.Width || tempHeight < 0 || tempHeight >= curBitmap.Height)
                                {
                                    tempArray[i * curBitmap.Width + j] = 255;
                                }
                                else
                                {
                                    tempArray[i * curBitmap.Width + j] = grayValues[tempHeight * curBitmap.Width + tempWidth];
                                }
                            }
                        }
                    }
                    else
                    {
                        double tempX, tempY, p, q;
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < curBitmap.Width; j++)
                            {
                                tempHeight = i - halfHeight;
                                tempWidth = j - halfWidth;
                                tempX = tempWidth / x;
                                tempY = tempHeight / y;
                                if (tempWidth > 0)
                                {
                                    xz = (int)tempX;
                                }
                                else
                                {
                                    xz = (int)(tempX - 1);
                                }
                                if (tempHeight > 0)
                                {
                                    yz = (int)tempY;
                                }
                                else
                                {
                                    yz = (int)(tempY - 1);
                                }

                                p = tempX - xz;
                                q = tempY - yz;
                                tempWidth = xz + halfWidth;
                                tempHeight = yz + halfHeight;
                                if (tempWidth < 0 || (tempWidth + 1) >= curBitmap.Width || tempHeight < 0 || (tempHeight + 1) >= curBitmap.Height)
                                {
                                    tempArray[i * curBitmap.Width + j] = 255;
                                }
                                else
                                {
                                    tempArray[i * curBitmap.Width + j] = (byte)((1.0 - q) * ((1.0 - p) * grayValues[tempHeight * curBitmap.Width + tempWidth] + p * grayValues[tempHeight * curBitmap.Width + tempWidth + 1]) +
                                        q * ((1.0 - p) * grayValues[(tempHeight + 1) * curBitmap.Width + tempWidth] + p * grayValues[(tempHeight + 1) * curBitmap.Width + 1 + tempWidth]));
                                }
                            }
                        }

                    }

                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();

            }
        }

        private void rotation_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                rotation rotForm = new rotation();
                if (rotForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    int degree = Convert.ToInt32(rotForm.GetDegree);
                    double radian = degree * Math.PI / 180.0;
                    double mySin = Math.Sin(radian);
                    double myCos = Math.Cos(radian);
                    int halfWidth = (int)(curBitmap.Width / 2);
                    int halfHeight = (int)(curBitmap.Height / 2);
                    int xr = 0;
                    int yr = 0;
                    int tempWidth = 0;
                    int tempHeight = 0;

                    byte[] tempArray = new byte[bytes];

                    double tempX, tempY, p, q;
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            tempHeight = i - halfHeight;
                            tempWidth = j - halfWidth;
                            tempX = tempWidth * myCos - tempHeight * mySin;
                            tempY = tempHeight * myCos + tempWidth * mySin;
                            if (tempWidth > 0)
                            {
                                xr = (int)tempX;
                            }
                            else
                            {
                                xr = (int)(tempX - 1);
                            }
                            if (tempHeight > 0)
                            {
                                yr = (int)tempY;
                            }
                            else
                            {
                                yr = (int)(tempY - 1);
                            }

                            p = tempX - xr;
                            q = tempY - yr;
                            tempWidth = xr + halfWidth;
                            tempHeight = yr + halfHeight;
                            if (tempWidth < 0 || (tempWidth + 1) >= curBitmap.Width || tempHeight < 0 || (tempHeight + 1) >= curBitmap.Height)
                            {
                                tempArray[i * curBitmap.Width + j] = 255;
                            }
                            else
                            {
                                tempArray[i * curBitmap.Width + j] = (byte)((1.0 - q) * ((1.0 - p) * grayValues[tempHeight * curBitmap.Width + tempWidth] + p * grayValues[tempHeight * curBitmap.Width + tempWidth + 1]) +
                                    q * ((1.0 - p) * grayValues[(tempHeight + 1) * curBitmap.Width + tempWidth] + p * grayValues[(tempHeight + 1) * curBitmap.Width + 1 + tempWidth]));
                            }

                        }
                    }

                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        //2018-02-05 12:16:31
        private void erode_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                struction struForm = new struction();
                struForm.Text = "腐蚀运算结构元素";
                if (struForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte flagStru = struForm.GetStruction;

                    byte[] tempArray = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = 255;
                    }

                    switch (flagStru)
                    {
                        case 0x11:
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x21:
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x12:
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x22:
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x14:
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x24:
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x18:
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j + 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x28:
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[(i - 2) * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j + 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        default:
                            MessageBox.Show("错误的结构元素！");
                            break;
                    }


                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void dilate_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                struction struForm = new struction();
                struForm.Text = "膨胀运算结构元素";
                if (struForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte flagStru = struForm.GetStruction;

                    byte[] tempArray = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = 255;
                    }

                    switch (flagStru)
                    {
                        case 0x11:
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x21:
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x12:
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x22:
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x14:
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x24:
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x18:
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j + 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x28:
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[(i - 2) * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j + 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        default:
                            MessageBox.Show("错误的结构元素！");
                            break;
                    }


                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void opening_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                struction struForm = new struction();
                struForm.Text = "开运算结构元素";
                if (struForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte flagStru = struForm.GetStruction;

                    byte[] temp1Array = new byte[bytes];
                    byte[] tempArray = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = temp1Array[i] = 255;
                    }

                    switch (flagStru)
                    {
                        case 0x11:
                            //腐蚀运算
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //膨胀运算
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x21:
                            //腐蚀运算
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //膨胀运算
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 2] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x12:
                            //腐蚀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //膨胀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x22:
                            //腐蚀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //膨胀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 2) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 2) * curBitmap.Width + j] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x14:
                            //腐蚀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //膨胀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x24:
                            //腐蚀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //膨胀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 2) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 2) * curBitmap.Width + j] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 2] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x18:
                            //腐蚀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j + 1] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //膨胀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j + 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x28:
                            //腐蚀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[(i - 2) * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i - 2) * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i - 1) * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[i * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[i * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i + 2) * curBitmap.Width + j + 2] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j - 2] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j + 1] == 0 &&
                                        grayValues[(i + 1) * curBitmap.Width + j + 2] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //膨胀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (temp1Array[(i - 2) * curBitmap.Width + j - 2] == 0 ||
                                        temp1Array[(i - 2) * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[(i - 2) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 2) * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[(i - 2) * curBitmap.Width + j + 2] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j - 2] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[(i - 1) * curBitmap.Width + j + 2] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 2] == 0 ||
                                        temp1Array[i * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[i * curBitmap.Width + j + 2] == 0 ||
                                        temp1Array[(i + 2) * curBitmap.Width + j - 2] == 0 ||
                                        temp1Array[(i + 2) * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[(i + 2) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 2) * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[(i + 2) * curBitmap.Width + j + 2] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j - 2] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j - 1] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j + 1] == 0 ||
                                        temp1Array[(i + 1) * curBitmap.Width + j + 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        default:
                            MessageBox.Show("错误的结构元素！");
                            break;
                    }


                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void closing_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                struction struForm = new struction();
                struForm.Text = "闭运算结构元素";
                if (struForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte flagStru = struForm.GetStruction;

                    byte[] temp1Array = new byte[bytes];
                    byte[] tempArray = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = temp1Array[i] = 255;
                    }

                    switch (flagStru)
                    {
                        case 0x11:
                            //膨胀运算
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //腐蚀运算
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x21:
                            //膨胀运算
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //腐蚀运算
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 2] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x12:
                            //膨胀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //腐蚀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x22:
                            //膨胀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //腐蚀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 2) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 2) * curBitmap.Width + j] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x14:
                            //膨胀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //腐蚀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x24:
                            //膨胀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //腐蚀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 2) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 2) * curBitmap.Width + j] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 2] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x18:
                            //膨胀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j + 1] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //腐蚀运算
                            for (int i = 1; i < curBitmap.Height - 1; i++)
                            {
                                for (int j = 1; j < curBitmap.Width - 1; j++)
                                {
                                    if (temp1Array[i * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j + 1] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        case 0x28:
                            //膨胀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (grayValues[(i - 2) * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i - 2) * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i - 1) * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[i * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[i * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i + 2) * curBitmap.Width + j + 2] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j - 2] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j + 1] == 0 ||
                                        grayValues[(i + 1) * curBitmap.Width + j + 2] == 0)
                                    {
                                        temp1Array[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            //腐蚀运算
                            for (int i = 2; i < curBitmap.Height - 2; i++)
                            {
                                for (int j = 2; j < curBitmap.Width - 2; j++)
                                {
                                    if (temp1Array[(i - 2) * curBitmap.Width + j - 2] == 0 &&
                                        temp1Array[(i - 2) * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[(i - 2) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 2) * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[(i - 2) * curBitmap.Width + j + 2] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j - 2] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[(i - 1) * curBitmap.Width + j + 2] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 2] == 0 &&
                                        temp1Array[i * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[i * curBitmap.Width + j + 2] == 0 &&
                                        temp1Array[(i + 2) * curBitmap.Width + j - 2] == 0 &&
                                        temp1Array[(i + 2) * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[(i + 2) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 2) * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[(i + 2) * curBitmap.Width + j + 2] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j - 2] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j - 1] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j + 1] == 0 &&
                                        temp1Array[(i + 1) * curBitmap.Width + j + 2] == 0)
                                    {
                                        tempArray[i * curBitmap.Width + j] = 0;
                                    }

                                }
                            }
                            break;
                        default:
                            MessageBox.Show("错误的结构元素！");
                            break;
                    }


                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void hitMiss_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                hitmiss hitAndMiss = new hitmiss();
                if (hitAndMiss.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    bool[] hitStru = hitAndMiss.GetHitStruction;
                    bool[] missStru = hitAndMiss.GetMissStruction;

                    byte[] tempArray = new byte[bytes];
                    byte[] temp1Array = new byte[bytes];
                    byte[] temp2Array = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = (byte)(255 - grayValues[i]);
                        temp1Array[i] = 255;
                        temp2Array[i] = 255;
                    }

                    for (int i = 1; i < curBitmap.Height - 1; i++)
                    {
                        for (int j = 1; j < curBitmap.Width - 1; j++)
                        {
                            if ((grayValues[(i - 1) * curBitmap.Width + j - 1] == 0 || hitStru[0] == false) &&
                                (grayValues[(i - 1) * curBitmap.Width + j] == 0 || hitStru[1] == false) &&
                                (grayValues[(i - 1) * curBitmap.Width + j + 1] == 0 || hitStru[2] == false) &&
                                (grayValues[i * curBitmap.Width + j - 1] == 0 || hitStru[3] == false) &&
                                (grayValues[i * curBitmap.Width + j] == 0 || hitStru[4] == false) &&
                                (grayValues[i * curBitmap.Width + j + 1] == 0 || hitStru[5] == false) &&
                                (grayValues[(i + 1) * curBitmap.Width + j - 1] == 0 || hitStru[6] == false) &&
                                (grayValues[(i + 1) * curBitmap.Width + j] == 0 || hitStru[7] == false) &&
                                (grayValues[(i + 1) * curBitmap.Width + j + 1] == 0 || hitStru[8] == false))
                            {
                                temp1Array[i * curBitmap.Width + j] = 0;
                            }

                        }
                    }

                    for (int i = 1; i < curBitmap.Height - 1; i++)
                    {
                        for (int j = 1; j < curBitmap.Width - 1; j++)
                        {
                            if ((tempArray[(i - 1) * curBitmap.Width + j - 1] == 0 || missStru[0] == false) &&
                                (tempArray[(i - 1) * curBitmap.Width + j] == 0 || missStru[1] == false) &&
                                (tempArray[(i - 1) * curBitmap.Width + j + 1] == 0 || missStru[2] == false) &&
                                (tempArray[i * curBitmap.Width + j - 1] == 0 || missStru[3] == false) &&
                                (tempArray[i * curBitmap.Width + j] == 0 || missStru[4] == false) &&
                                (tempArray[i * curBitmap.Width + j + 1] == 0 || missStru[5] == false) &&
                                (tempArray[(i + 1) * curBitmap.Width + j - 1] == 0 || missStru[6] == false) &&
                                (tempArray[(i + 1) * curBitmap.Width + j] == 0 || missStru[7] == false) &&
                                (tempArray[(i + 1) * curBitmap.Width + j + 1] == 0 || missStru[8] == false))
                            {
                                temp2Array[i * curBitmap.Width + j] = 0;
                            }

                        }
                    }

                    for (int i = 0; i < bytes; i++)
                    {
                        if (temp1Array[i] == 0 && temp2Array[i] == 0)
                        {
                            tempArray[i] = 0;
                        }
                        else
                        {
                            tempArray[i] = 255;
                        }
                    }

                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        //2018-02-05 13:06:07

        private Complex[] fft(Complex[] sourceData, int countN)
        {
            int r = Convert.ToInt32(Math.Log(countN, 2));//求fft的级数

            //求加权系数W
            Complex[] w = new Complex[countN / 2];
            Complex[] interVar1 = new Complex[countN];
            Complex[] interVar2 = new Complex[countN];

            interVar1 = (Complex[])sourceData.Clone();

            for (int i = 0; i < countN / 2; i++)
            {
                double angle = -i * Math.PI * 2 / countN;
                w[i] = new Complex(Math.Cos(angle), Math.Sin(angle));
            }

            //核心部分
            for (int i = 0; i < r; i++)
            {
                int interval = 1 << i;
                int halfN = 1 << (r - i);
                for (int j = 0; j < interval; j++)
                {
                    int gap = j * halfN;
                    for (int k = 0; k < halfN / 2; k++)
                    {
                        interVar2[k + gap] = interVar1[k + gap] + interVar1[k + gap + halfN / 2];
                        interVar2[k + halfN / 2 + gap] = (interVar1[k + gap] - interVar1[k + gap + halfN / 2]) * w[k * interval];
                    }
                }
                interVar1 = (Complex[])interVar2.Clone();
            }

            for (uint j = 0; j < countN; j++)
            {
                uint rev = 0;
                uint num = j;
                for (int i = 0; i < r; i++)
                {
                    rev <<= 1;
                    rev |= num & 1;
                    num >>= 1;
                }
                interVar2[rev] = interVar1[j];
            }
            return interVar2;
        }

        private Complex[] ifft(Complex[] sourceData, int countN)
        {
            for (int i = 0; i < countN; i++)
            {
                sourceData[i] = sourceData[i].Conjugate();
            }

            Complex[] interVar = new Complex[countN];
            interVar = fft(sourceData, countN);

            for (int i = 0; i < countN; i++)
            {
                interVar[i] = new Complex(interVar[i].Real / countN, -interVar[i].Imaginary / countN);
            }

            return interVar;
        }

        private Complex[] fft2(byte[] imageData, int imageWidth, int imageHeight, bool inv)
        {
            int bytes = imageWidth * imageHeight;
            byte[] bmpValues = new byte[bytes];
            Complex[] tempCom1 = new Complex[bytes];

            bmpValues = (byte[])imageData.Clone();

            for (int i = 0; i < bytes; i++)
            {
                if (inv == true)
                {
                    if ((i / imageWidth + i % imageWidth) % 2 == 0)
                    {
                        tempCom1[i] = new Complex(bmpValues[i], 0);
                    }
                    else
                    {
                        tempCom1[i] = new Complex(-bmpValues[i], 0);
                    }
                }
                else
                {
                    tempCom1[i] = new Complex(bmpValues[i], 0);
                }
            }

            Complex[] tempCom2 = new Complex[imageWidth];
            Complex[] tempCom3 = new Complex[imageWidth];
            for (int i = 0; i < imageHeight; i++)//水平方向
            {
                for (int j = 0; j < imageWidth; j++)
                {
                    tempCom2[j] = tempCom1[i * imageWidth + j];
                }
                tempCom3 = fft(tempCom2, imageWidth);
                for (int j = 0; j < imageWidth; j++)
                {
                    tempCom1[i * imageWidth + j] = tempCom3[j];
                }
            }

            Complex[] tempCom4 = new Complex[imageHeight];
            Complex[] tempCom5 = new Complex[imageHeight];
            for (int i = 0; i < imageWidth; i++)//垂直方向
            {
                for (int j = 0; j < imageHeight; j++)
                {
                    tempCom4[j] = tempCom1[j * imageWidth + i];
                }
                tempCom5 = fft(tempCom4, imageHeight);
                for (int j = 0; j < imageHeight; j++)
                {
                    tempCom1[j * imageHeight + i] = tempCom5[j];
                }
            }

            return tempCom1;
        }

        private byte[] ifft2(Complex[] freData, int imageWidth, int imageHeight, bool inv)
        {
            int bytes = imageWidth * imageHeight;
            byte[] bmpValues = new byte[bytes];
            Complex[] tempCom1 = new Complex[bytes];

            tempCom1 = (Complex[])freData.Clone();

            Complex[] tempCom2 = new Complex[imageWidth];
            Complex[] tempCom3 = new Complex[imageWidth];
            for (int i = 0; i < imageHeight; i++)//水平方向
            {
                for (int j = 0; j < imageWidth; j++)
                {
                    tempCom2[j] = tempCom1[i * imageWidth + j];
                }
                tempCom3 = ifft(tempCom2, imageWidth);
                for (int j = 0; j < imageWidth; j++)
                {
                    tempCom1[i * imageWidth + j] = tempCom3[j];
                }
            }

            Complex[] tempCom4 = new Complex[imageHeight];
            Complex[] tempCom5 = new Complex[imageHeight];
            for (int i = 0; i < imageWidth; i++)//垂直方向
            {
                for (int j = 0; j < imageHeight; j++)
                {
                    tempCom4[j] = tempCom1[j * imageWidth + i];
                }
                tempCom5 = ifft(tempCom4, imageHeight);
                for (int j = 0; j < imageHeight; j++)
                {
                    tempCom1[j * imageHeight + i] = tempCom5[j];
                }
            }

            double tempDouble;
            for (int i = 0; i < bytes; i++)
            {
                if (inv == true)
                {
                    if ((i / curBitmap.Width + i % curBitmap.Width) % 2 == 0)
                    {
                        tempDouble = tempCom1[i].Real;
                    }
                    else
                    {
                        tempDouble = -tempCom1[i].Real;
                    }
                }
                else
                {
                    tempDouble = tempCom1[i].Real;
                }

                if (tempDouble > 255)
                {
                    bmpValues[i] = 255;
                }
                else
                {
                    if (tempDouble < 0)
                    {
                        bmpValues[i] = 0;
                    }
                    else
                    {
                        bmpValues[i] = Convert.ToByte(tempDouble);
                    }
                }
            }

            return bmpValues;
        }

        private void amplitude_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                IntPtr ptr = bmpData.Scan0;
                int bytes = curBitmap.Width * curBitmap.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                Complex[] freDom = new Complex[bytes];
                double[] tempArray = new double[bytes];

                freDom = fft2(grayValues, curBitmap.Width, curBitmap.Height, true);

                for (int i = 0; i < bytes; i++)
                {
                    tempArray[i] = Math.Log(1 + freDom[i].Abs(), 2);
                }

                //灰度级拉伸
                double a = 1000.0, b = 0.0;
                double p;
                for (int i = 0; i < bytes; i++)
                {
                    if (a > tempArray[i])
                    {
                        a = tempArray[i];
                    }
                    if (b < tempArray[i])
                    {
                        b = tempArray[i];
                    }
                }
                p = 255.0 / (b - a);
                for (int i = 0; i < bytes; i++)
                {
                    grayValues[i] = (byte)(p * (tempArray[i] - a) + 0.5);
                }


                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curBitmap.UnlockBits(bmpData);

                Invalidate();
            }
        }

        private void phase_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                IntPtr ptr = bmpData.Scan0;
                int bytes = curBitmap.Width * curBitmap.Height;
                byte[] grayValues = new byte[bytes];
                System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                Complex[] freDom = new Complex[bytes];
                double[] tempArray = new double[bytes];
                freDom = fft2(grayValues, curBitmap.Width, curBitmap.Height, false);

                for (int i = 0; i < bytes; i++)
                {
                    tempArray[i] = freDom[i].Angle() + 2 * Math.PI;
                }

                //灰度级拉伸
                double a = 1000.0, b = 0.0;
                double p;
                for (int i = 0; i < bytes; i++)
                {
                    if (a > tempArray[i])
                    {
                        a = tempArray[i];
                    }
                    if (b < tempArray[i])
                    {
                        b = tempArray[i];
                    }
                }
                p = 255.0 / (b - a);
                for (int i = 0; i < bytes; i++)
                {
                    grayValues[i] = (byte)(p * (tempArray[i] - a) + 0.5);
                }

                System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                curBitmap.UnlockBits(bmpData);

                Invalidate();
            }
        }

        private void freGran_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                granularity granForm = new granularity();
                if (granForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    Complex[] freDom = new Complex[bytes];
                    Complex[] tempDD = new Complex[bytes];
                    byte[] tempArray = new byte[bytes];

                    byte[] tempRadius = new byte[6];
                    tempRadius = granForm.GetRadius;
                    byte flag = granForm.GetFlag;
                    int minLen = Math.Min(curBitmap.Width, curBitmap.Height);
                    double[] radius = new double[6];
                    for (int i = 0; i < 6; i++)
                    {
                        radius[i] = tempRadius[i] * minLen / 100;
                    }

                    freDom = fft2(grayValues, curBitmap.Width, curBitmap.Height, true);

                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            double distance = (double)((j - curBitmap.Width / 2) * (j - curBitmap.Width / 2) + (i - curBitmap.Height / 2) * (i - curBitmap.Height / 2));
                            distance = Math.Sqrt(distance);

                            switch (flag)
                            {
                                case 0:
                                    if (distance > radius[0])
                                    {
                                        tempDD[i * curBitmap.Width + j] = new Complex(0.0, 0.0);
                                    }
                                    else
                                        tempDD[i * curBitmap.Width + j] = new Complex(1.0, 1.0);
                                    break;
                                case 1:
                                    if (distance < radius[1] && distance > radius[2])
                                    {
                                        tempDD[i * curBitmap.Width + j] = new Complex(0.0, 0.0);
                                    }
                                    else
                                        tempDD[i * curBitmap.Width + j] = new Complex(1.0, 1.0);
                                    break;
                                case 2:
                                    if (distance > radius[3] || distance < radius[4])
                                    {
                                        tempDD[i * curBitmap.Width + j] = new Complex(0.0, 0.0);
                                    }
                                    else
                                        tempDD[i * curBitmap.Width + j] = new Complex(1.0, 1.0);
                                    break;
                                case 3:
                                    if (distance < radius[5])
                                    {
                                        tempDD[i * curBitmap.Width + j] = new Complex(0.0, 0.0);
                                    }
                                    else
                                        tempDD[i * curBitmap.Width + j] = new Complex(1.0, 1.0);
                                    break;
                                default:
                                    MessageBox.Show("无效！");
                                    break;
                            }
                        }
                    }

                    for (int i = 0; i < bytes; i++)
                        freDom[i] *= tempDD[i];

                    tempArray = ifft2(freDom, curBitmap.Width, curBitmap.Height, true);
                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void freOri_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                orientation orieForm = new orientation();
                if (orieForm.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    Complex[] freDom = new Complex[bytes];
                    byte[] tempArray = new byte[bytes];

                    int[] tempOrient = new int[2];
                    tempOrient = orieForm.GetOrient;
                    byte flag = 1;
                    if (tempOrient[1] <= 0)
                    {
                        flag = 1;
                    }
                    if (tempOrient[0] <= 0 && tempOrient[1] > 0)
                    {
                        flag = 2;
                    }
                    if (tempOrient[0] > 0 && tempOrient[1] < 180)
                    {
                        flag = 3;
                    }
                    if (tempOrient[1] > 180)
                    {
                        flag = 4;
                    }
                    freDom = fft2(grayValues, curBitmap.Width, curBitmap.Height, true);

                    double tempD;

                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            tempD = (Math.Atan2(curBitmap.Height / 2 - i, j - curBitmap.Width / 2)) * 180 / Math.PI;

                            switch (flag)
                            {
                                case 1:
                                    if ((tempD <= tempOrient[1] && tempD >= tempOrient[0]) || (tempD <= (tempOrient[1] + 180) && tempD >= (tempOrient[0] + 180)))
                                    {
                                        freDom[i * curBitmap.Width + j] = new Complex(0.0, 0.0);
                                    }
                                    break;
                                case 2:
                                    if ((tempD <= tempOrient[1] && tempD >= tempOrient[0] /*&& tempD != 0*/) || (tempD <= tempOrient[1] - 180 && tempD > -180) || (tempD > tempOrient[0] + 180 && tempD <= 180))
                                    {
                                        freDom[i * curBitmap.Width + j] = new Complex(0.0, 0.0);
                                    }
                                    break;
                                case 3:
                                    if ((tempD <= tempOrient[1] && tempD >= tempOrient[0]) || (tempD <= tempOrient[1] - 180 && tempD >= tempOrient[0] - 180))
                                    {
                                        freDom[i * curBitmap.Width + j] = new Complex(0.0, 0.0);
                                    }
                                    break;
                                case 4:
                                    if (((tempD <= tempOrient[1] - 180) && (tempD >= tempOrient[0] - 180)) || (tempD <= tempOrient[1] - 360 && tempD >= -180) || (tempD >= tempOrient[0] && tempD <= 180))
                                    {
                                        freDom[i * curBitmap.Width + j] = new Complex(0.0, 0.0);
                                    }
                                    break;
                                default:
                                    MessageBox.Show("无效！");
                                    break;
                            }

                        }
                    }

                    tempArray = ifft2(freDom, curBitmap.Width, curBitmap.Height, true);
                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        //2018-02-05 13:20:21
        private void noise_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                noiseModel noise = new noiseModel();
                if (noise.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                        //curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                    double temp = 0;
                    byte flagNoise = noise.GetFlag;
                    double[] paraNoise = new double[2];
                    paraNoise = noise.GetParaN;

                    Random r1, r2;
                    double v1, v2;
                    r1 = new Random(unchecked((int)DateTime.Now.Ticks));
                    r2 = new Random(~unchecked((int)DateTime.Now.Ticks));

                    for (int i = 0; i < bytes; i++)
                    {
                        switch (flagNoise)
                        {
                            case 0:
                                do
                                {
                                    v1 = r1.NextDouble();
                                }
                                while (v1 <= 0.00000000001);
                                v2 = r2.NextDouble();
                                temp = Math.Sqrt(-2 * Math.Log(v1)) * Math.Cos(2 * Math.PI * v2) * paraNoise[1] + paraNoise[0];
                                break;
                            case 1:
                                do
                                {
                                    v1 = r1.NextDouble();
                                }
                                while (v1 >= 0.9999999999);
                                temp = paraNoise[0] + Math.Sqrt(-1 * paraNoise[1] * Math.Log(1 - v1));
                                break;
                            case 2:
                                do
                                {
                                    v1 = r1.NextDouble();
                                }
                                while (v1 >= 0.9999999999);
                                temp = -1 * Math.Log(1 - v1) / paraNoise[0];
                                break;
                            case 3:
                                v1 = r1.NextDouble();
                                if (v1 <= paraNoise[0])
                                    temp = -500;
                                else if (v1 >= (1 - paraNoise[1]))
                                    temp = 500;
                                else
                                    temp = 0;
                                break;
                            default:
                                MessageBox.Show("无效！");
                                break;
                        }
                        temp = temp + grayValues[i];

                        if (temp > 255)
                        {
                            grayValues[i] = 255;
                        }
                        else if (temp < 0)
                        {
                            grayValues[i] = 0;
                        }
                        else
                            grayValues[i] = Convert.ToByte(temp);
                    }
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }
                noise.Close();
                Invalidate();
            }
        }

        private void meanMedian_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                meanMedian meaAndMed = new meanMedian();
                if (meaAndMed.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    Console.WriteLine(curBitmap.PixelFormat);
                    //System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte[] tempArray = new byte[bytes];

                    byte sideLength = meaAndMed.GetLength;
                    byte halfLength = (byte)(sideLength / 2);
                    bool flagM = meaAndMed.GetFlag;

                    Console.WriteLine("meanMedian_Click : " + curBitmap.Height + "," + curBitmap.Width);
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            switch (sideLength)
                            {
                                case 3:
                                    if (flagM == false)
                                    {
                                        tempArray[i * curBitmap.Width + j] = (byte)((grayValues[i * curBitmap.Width + j] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]) / 9);

                                    }
                                    else
                                    {
                                        byte[] sortArray = new byte[] {grayValues[i * curBitmap.Width + j],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]};
                                        Sort(sortArray);
                                        tempArray[i * curBitmap.Width + j] = sortArray[4];
                                    }
                                    break;
                                case 5:
                                    if (flagM == false)
                                    {
                                        tempArray[i * curBitmap.Width + j] = (byte)((grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2)) % curBitmap.Width] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1)) % curBitmap.Width] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + j] +
                                            grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)]) / 25);
                                    }
                                    else
                                    {
                                        byte[] sortArray = new byte[] {grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2)) % curBitmap.Width],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1)) % curBitmap.Width],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + j],
                                            grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)]};
                                        Sort(sortArray);
                                        tempArray[i * curBitmap.Width + j] = sortArray[12];
                                    }
                                    break;
                                case 7:
                                    if (flagM == false)
                                    {
                                        tempArray[i * curBitmap.Width + j] = (byte)((grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2)) % curBitmap.Width] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1)) % curBitmap.Width] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + j] +
                                            grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + j] +
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)]) / 49);
                                    }
                                    else
                                    {
                                        byte[] sortArray = new byte[] {grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2)) % curBitmap.Width],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1)) % curBitmap.Width],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + j],
                                            grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + ((j + 3) % curBitmap.Width)],
                                            grayValues[i * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)],
                                            grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)],
                                            grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)],
                                            grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)],
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)],
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)],
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)],
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)],
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + j],
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)],
                                            grayValues[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)]};
                                        Sort(sortArray);
                                        tempArray[i * curBitmap.Width + j] = sortArray[24];
                                    }
                                    break;
                                default:
                                    MessageBox.Show("无效！");
                                    break;
                            }
                        }
                    }

                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void Sort(byte[] list)
        {
            int min;
            for (int i = 0; i < list.Length - 1; i++)
            {
                min = i;
                for (int j = i + 1; j < list.Length; j++)
                {
                    if (list[j] < list[min])
                        min = j;
                }
                byte t = list[min];
                list[min] = list[i];
                list[i] = t;
            }
        }

        private void grayMor_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                morphologic grayMor = new morphologic();
                if (grayMor.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte[] tempArray = new byte[bytes];
                    byte[] struEle = new byte[25];
                    struEle = grayMor.GetStruction;

                    tempArray = grayClose(grayValues, struEle, curBitmap.Height, curBitmap.Width);
                    grayValues = grayOpen(tempArray, struEle, curBitmap.Height, curBitmap.Width);

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private byte[] grayDelation(byte[] grayImage, byte[] se, int tHeight, int tWidth)
        {
            byte[] tempImage = new byte[grayImage.Length];

            for (int i = 0; i < tHeight; i++)
            {
                for (int j = 0; j < tWidth; j++)
                {
                    int[] cou = new int[]{grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + (Math.Abs(j - 2)) % tWidth] * se[0],
								        grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + (Math.Abs(j - 1)) % tWidth] * se[1],
								        grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + j] * se[2],
								        grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + ((j + 1) % tWidth)] * se[3],
								        grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + ((j + 2) % tWidth)] * se[4],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * se[5],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * se[6],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + j] * se[7],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + ((j + 1) % tWidth)] * se[8],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + ((j + 2) % tWidth)] * se[9],
								        grayImage[i * tWidth + (Math.Abs(j - 2) % tWidth)] * se[10],
								        grayImage[i * tWidth + (Math.Abs(j - 1) % tWidth)] * se[11],
								        grayImage[i * tWidth + j] * se[12],
								        grayImage[i * tWidth + ((j + 1) % tWidth)] * se[13],
								        grayImage[i * tWidth + ((j + 2) % tWidth)] * se[14],								        
								        grayImage[((i + 1) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * se[15],
								        grayImage[((i + 1) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * se[16],
								        grayImage[((i + 1) % tHeight) * tWidth + j] * se[17],
								        grayImage[((i + 1) % tHeight) * tWidth + ((j + 1) % tWidth)] * se[18],
								        grayImage[((i + 1) % tHeight) * tWidth + ((j + 2) % tWidth)] * se[19],
                                        grayImage[((i + 2) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * se[20],
								        grayImage[((i + 2) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * se[21],
								        grayImage[((i + 2) % tHeight) * tWidth + j] * se[22],
								        grayImage[((i + 2) % tHeight) * tWidth + ((j + 1) % tWidth)] * se[23],
								        grayImage[((i + 2) % tHeight) * tWidth + ((j + 2) % tWidth)] * se[24]};
                    int maxim = cou[0];
                    for (int k = 1; k < 25; k++)
                    {
                        if (cou[k] > maxim)
                        {
                            maxim = cou[k];
                        }
                    }
                    tempImage[i * tWidth + j] = (byte)maxim;
                }
            }

            return tempImage;
        }

        private byte[] grayErode(byte[] grayImage, byte[] se, int tHeight, int tWidth)
        {
            byte[] tempImage = new byte[grayImage.Length];

            byte[] tempSe = new byte[25];
            tempSe = (byte[])se.Clone();
            for (int k = 0; k < 25; k++)
            {
                if (tempSe[k] == 0)
                    tempSe[k] = 255;
            }
            for (int i = 0; i < tHeight; i++)
            {
                for (int j = 0; j < tWidth; j++)
                {
                    int[] cou = new int[]{grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + (Math.Abs(j - 2)) % tWidth] * tempSe[0],
								        grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + (Math.Abs(j - 1)) % tWidth] * tempSe[1],
								        grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + j] * tempSe[2],
								        grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + ((j + 1) % tWidth)] * tempSe[3],
								        grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + ((j + 2) % tWidth)] * tempSe[4],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * tempSe[5],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * tempSe[6],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + j] * tempSe[7],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + ((j + 1) % tWidth)] * tempSe[8],
								        grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + ((j + 2) % tWidth)] * tempSe[9],
								        grayImage[i * tWidth + (Math.Abs(j - 2) % tWidth)] * tempSe[10],
								        grayImage[i * tWidth + (Math.Abs(j - 1) % tWidth)] * tempSe[11],
								        grayImage[i * tWidth + j] * tempSe[12],
								        grayImage[i * tWidth + ((j + 1) % tWidth)] * tempSe[13],
								        grayImage[i * tWidth + ((j + 2) % tWidth)] * tempSe[14],								        
								        grayImage[((i + 1) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * tempSe[15],
								        grayImage[((i + 1) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * tempSe[16],
								        grayImage[((i + 1) % tHeight) * tWidth + j] * tempSe[17],
								        grayImage[((i + 1) % tHeight) * tWidth + ((j + 1) % tWidth)] * tempSe[18],
								        grayImage[((i + 1) % tHeight) * tWidth + ((j + 2) % tWidth)] * tempSe[19],
                                        grayImage[((i + 2) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * tempSe[20],
								        grayImage[((i + 2) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * tempSe[21],
								        grayImage[((i + 2) % tHeight) * tWidth + j] * tempSe[22],
								        grayImage[((i + 2) % tHeight) * tWidth + ((j + 1) % tWidth)] * tempSe[23],
								        grayImage[((i + 2) % tHeight) * tWidth + ((j + 2) % tWidth)] * tempSe[24]};
                    int minimum = cou[0];
                    for (int k = 1; k < 25; k++)
                    {
                        if (cou[k] < minimum)
                        {
                            minimum = cou[k];
                        }
                    }
                    tempImage[i * tWidth + j] = (byte)minimum;
                }
            }

            return tempImage;
        }

        private byte[] grayOpen(byte[] grayImage, byte[] se, int tHeight, int tWidth)
        {
            byte[] tempImage = new byte[grayImage.Length];
            tempImage = grayErode(grayImage, se, tHeight, tWidth);
            return (grayDelation(tempImage, se, tHeight, tWidth));
        }

        private byte[] grayClose(byte[] grayImage, byte[] se, int tHeight, int tWidth)
        {
            byte[] tempImage = new byte[grayImage.Length];
            tempImage = grayDelation(grayImage, se, tHeight, tWidth);
            return (grayErode(tempImage, se, tHeight, tWidth));
        }

        private void wavelet_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                wavelet dwt = new wavelet();
                if (dwt.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    double[] tempA = new double[bytes];
                    double[] tempB = new double[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempA[i] = Convert.ToDouble(grayValues[i]);
                    }

                    byte thresholding = dwt.GetThresholding;
                    byte dwtSeries = dwt.GetSeries;
                    byte flagFilter = dwt.GetFlagV;
                    double[] lowFilter = null;
                    double[] highFilter = null;

                    switch (flagFilter & 0x0f)
                    {
                        case 0://haar
                            lowFilter = new double[] { 0.70710678118655, 0.70710678118655 };
                            break;
                        case 1://daubechies2
                            lowFilter = new double[] { 0.48296291314453, 0.83651630373780, 0.22414386804201, -0.12940952255126 };
                            break;
                        case 2://daubechies3
                            lowFilter = new double[] { 0.33267055295008, 0.80689150931109, 0.45987750211849, -0.13501102001025, -0.08544127388203, 0.03522629188571 };
                            break;
                        case 3://daubechies4
                            lowFilter = new double[] { 0.23037781330889, 0.71484657055291, 0.63088076792986, -0.02798376941686, -0.18703481171909, 0.03084138183556, 0.03288301166689, -0.01059740178507 };
                            break;
                        case 4://daubechies5
                            lowFilter = new double[] { 0.16010239797419, 0.60382926979719, 0.72430852843778, 0.13842814590132, -0.24229488706638, -0.03224486958464, 0.07757149384005, -0.00624149021280, -0.01258075199908, 0.00333572528547 };
                            break;
                        case 5://daubechies6
                            lowFilter = new double[] { 0.11154074335011, 0.49462389039845, 0.75113390802110, 0.31525035170920, -0.22626469396544, -0.12976686756726, 0.09750160558732, 0.02752286553031, -0.03158203931849, 0.00055384220116, 0.00477725751195, -0.00107730108531 };
                            break;
                        default:
                            MessageBox.Show("无效！");
                            break;
                    }

                    highFilter = new double[lowFilter.Length];
                    for (int i = 0; i < lowFilter.Length; i++)
                    {
                        highFilter[i] = Math.Pow(-1, i) * lowFilter[lowFilter.Length - 1 - i];
                    }

                    for (int k = 0; k < dwtSeries; k++)
                    {
                        int coef = (int)Math.Pow(2, k);
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            if (i < curBitmap.Height / coef)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (j < curBitmap.Width / coef)
                                    {
                                        tempB[i * curBitmap.Width / coef + j] = tempA[i * curBitmap.Width + j];
                                    }
                                }
                            }
                        }
                        wavelet2D(ref tempB, lowFilter, highFilter, coef);
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            if (i < curBitmap.Height / coef)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (j < curBitmap.Width / coef)
                                    {
                                        tempA[i * curBitmap.Width + j] = tempB[i * curBitmap.Width / coef + j];
                                    }
                                }
                            }
                        }

                        if ((flagFilter & 0xf0) == 0x10)
                        {
                            for (int l = 0; l < bytes; l++)
                            {
                                if (tempA[l] < thresholding && tempA[l] > -thresholding)
                                    tempA[l] = 0;
                            }
                        }
                        else
                        {
                            for (int l = 0; l < bytes; l++)
                            {
                                if (tempA[l] >= thresholding)
                                    tempA[l] = tempA[l] - thresholding;
                                else
                                {
                                    if (tempA[l] <= -thresholding)
                                        tempA[l] = tempA[l] + thresholding;
                                    else
                                        tempA[l] = 0;
                                }
                            }
                        }
                    }

                    for (int k = dwtSeries - 1; k >= 0; k--)
                    {
                        int coef = (int)Math.Pow(2, k);
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            if (i < curBitmap.Height / coef)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (j < curBitmap.Width / coef)
                                    {
                                        tempB[i * curBitmap.Width / coef + j] = tempA[i * curBitmap.Width + j];
                                    }
                                }
                            }
                        }
                        iwavelet2D(ref tempB, lowFilter, highFilter, coef);
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            if (i < curBitmap.Height / coef)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (j < curBitmap.Width / coef)
                                    {
                                        tempA[i * curBitmap.Width + j] = tempB[i * curBitmap.Width / coef + j];
                                    }
                                }
                            }
                        }
                    }

                    for (int i = 0; i < bytes; i++)
                    {
                        if (tempA[i] >= 255)
                            tempA[i] = 255;
                        if (tempA[i] <= 0)
                            tempA[i] = 0;
                        grayValues[i] = Convert.ToByte(tempA[i]);
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void wavelet1D(double[] scl0, double[] p, double[] q, out  double[] scl1, out double[] wvl1)
        {
            int temp;
            int sclLen = scl0.Length;
            int pLen = p.Length;
            scl1 = new double[sclLen / 2];
            wvl1 = new double[sclLen / 2];

            for (int i = 0; i < sclLen / 2; i++)
            {
                scl1[i] = 0.0;
                wvl1[i] = 0.0;
                for (int j = 0; j < pLen; j++)
                {
                    temp = (j + i * 2) % sclLen;
                    scl1[i] += p[j] * scl0[temp];
                    wvl1[i] += q[j] * scl0[temp];
                }
            }
        }

        private void iwavelet1D(out double[] scl0, double[] p, double[] q, double[] scl1, double[] wvl1)
        {
            int temp;
            int sclLen = scl1.Length;
            int pLen = p.Length;
            scl0 = new double[sclLen * 2];

            for (int i = 0; i < sclLen; i++)
            {
                scl0[2 * i + 1] = 0.0;
                scl0[2 * i] = 0.0;
                for (int j = 0; j < pLen / 2; j++)
                {
                    temp = (i - j + sclLen) % sclLen;
                    scl0[2 * i + 1] += p[2 * j + 1] * scl1[temp] + q[2 * j + 1] * wvl1[temp];
                    scl0[2 * i] += p[2 * j] * scl1[temp] + q[2 * j] * wvl1[temp];
                }
            }
        }

        private void wavelet2D(ref double[] dataImage, double[] p, double[] q, int series/*out double[] scl1, out double[] wvl1*/)
        {
            double[] s = new double[curBitmap.Width / series];
            double[] s1 = new double[curBitmap.Width / (2 * series)];
            double[] w1 = new double[curBitmap.Width / (2 * series)];
            for (int i = 0; i < curBitmap.Height / series; i++)
            {
                for (int j = 0; j < curBitmap.Width / series; j++)
                {
                    s[j] = dataImage[i * curBitmap.Width / series + j];
                }
                wavelet1D(s, p, q, out s1, out w1);

                for (int j = 0; j < curBitmap.Width / series; j++)
                {
                    if (j < curBitmap.Width / (2 * series))
                        dataImage[i * curBitmap.Width / series + j] = s1[j];
                    else
                        dataImage[i * curBitmap.Width / series + j] = w1[j - curBitmap.Width / (2 * series)];
                }
            }

            for (int i = 0; i < curBitmap.Width / series; i++)
            {
                for (int j = 0; j < curBitmap.Height / series; j++)
                {
                    s[j] = dataImage[j * curBitmap.Width / series + i];
                }
                wavelet1D(s, p, q, out s1, out w1);
                for (int j = 0; j < curBitmap.Height / series; j++)
                {
                    if (j < curBitmap.Height / (2 * series))
                        dataImage[j * curBitmap.Width / series + i] = s1[j];
                    else
                        dataImage[j * curBitmap.Width / series + i] = w1[j - curBitmap.Height / (2 * series)];
                }
            }
        }

        private void iwavelet2D(ref double[] dataImage, double[] p, double[] q, int series)
        {
            double[] s = new double[curBitmap.Width / series];
            double[] s1 = new double[curBitmap.Width / (2 * series)];
            double[] w1 = new double[curBitmap.Width / (2 * series)];
            for (int i = 0; i < curBitmap.Width / series; i++)
            {
                for (int j = 0; j < curBitmap.Height / series; j++)
                {
                    if (j < curBitmap.Height / (2 * series))
                        s1[j] = dataImage[j * curBitmap.Width / series + i];
                    else
                        w1[j - curBitmap.Height / (2 * series)] = dataImage[j * curBitmap.Width / series + i];
                }
                iwavelet1D(out s, p, q, s1, w1);
                for (int j = 0; j < curBitmap.Height / series; j++)
                {
                    dataImage[j * curBitmap.Width / series + i] = s[j];
                }
            }
            for (int i = 0; i < curBitmap.Height / series; i++)
            {
                for (int j = 0; j < curBitmap.Width / series; j++)
                {
                    if (j < curBitmap.Width / (2 * series))
                        s1[j] = dataImage[i * curBitmap.Width / series + j];
                    else
                        w1[j - curBitmap.Width / (2 * series)] = dataImage[i * curBitmap.Width / series + j];
                }
                iwavelet1D(out s, p, q, s1, w1);
                for (int j = 0; j < curBitmap.Width / series; j++)
                {
                    dataImage[i * curBitmap.Width / series + j] = s[j];
                }
            }
        }

        private void gauss_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                gauss7 gaussFilter = new gauss7();
                if (gaussFilter.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    double[] tempArray;
                    double[] tempImage = new double[bytes];
                    double sigma = gaussFilter.GetSigma;
                    for (int i = 0; i < bytes; i++)
                    {
                        tempImage[i] = Convert.ToDouble(grayValues[i]);
                    }

                    gaussSmooth(tempImage, out tempArray, sigma);

                    for (int i = 0; i < bytes; i++)
                    {
                        if (tempArray[i] > 255)
                            grayValues[i] = 255;
                        else if (tempArray[i] < 0)
                            grayValues[i] = 0;
                        else
                            grayValues[i] = Convert.ToByte(tempArray[i]);
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void gaussSmooth(double[] inputImage, out double[] outputImage, double sigma)
        {
            double std2 = 2 * sigma * sigma;
            int radius = Convert.ToInt16(Math.Ceiling(3 * sigma));
            int filterWidth = 2 * radius + 1;
            double[] filter = new double[filterWidth];
            outputImage = new double[inputImage.Length];
            int length = Convert.ToInt16(Math.Sqrt(inputImage.Length));
            double[] tempImage = new double[inputImage.Length];

            double sum = 0;
            for (int i = 0; i < filterWidth; i++)
            {
                int xx = (i - radius) * (i - radius);
                filter[i] = Math.Exp(-xx / std2);
                sum += filter[i];
            }
            for (int i = 0; i < filterWidth; i++)
            {
                filter[i] = filter[i] / sum;
            }

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < length; j++)
                {
                    double temp = 0;
                    for (int k = -radius; k <= radius; k++)
                    {
                        int rem = (Math.Abs(j + k)) % length;
                        temp += inputImage[i * length + rem] * filter[k + radius];
                    }
                    tempImage[i * length + j] = temp;
                }
            }
            for (int j = 0; j < length; j++)
            {
                for (int i = 0; i < length; i++)
                {
                    double temp = 0;
                    for (int k = -radius; k <= radius; k++)
                    {
                        int rem = (Math.Abs(i + k)) % length;
                        temp += tempImage[rem * length + j] * filter[k + radius];
                    }
                    outputImage[i * length + j] = temp;
                }
            }
        }

        private void statistic_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                stati staticSmooth = new stati();
                if (staticSmooth.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte[] tempArray = new byte[bytes];
                    double thresholding = staticSmooth.GetThresholding;
                    bool flag = staticSmooth.GetWindows;

                    if (flag == false)
                    {
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < curBitmap.Width; j++)
                            {
                                double mu = 0, sigma = 0;
                                mu = (grayValues[i * curBitmap.Width + j] +
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                                        grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                        grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]) / 9;

                                sigma = Math.Sqrt((Math.Pow((grayValues[i * curBitmap.Width + j] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - mu), 2) +
                                        Math.Pow((grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - mu), 2) +
                                        Math.Pow((grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - mu), 2)) / 9);

                                if (Math.Abs(grayValues[i * curBitmap.Width + j] - mu) < sigma * thresholding)
                                    tempArray[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j];
                                else
                                    tempArray[i * curBitmap.Width + j] = Convert.ToByte(mu);

                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < curBitmap.Width; j++)
                            {
                                double mu = 0, sigma = 0;
                                mu = (grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2)) % curBitmap.Width] +
                                        grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1)) % curBitmap.Width] +
                                        grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + j] +
                                        grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                        grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                        grayValues[i * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                        grayValues[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                        grayValues[i * curBitmap.Width + j] +
                                        grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                        grayValues[i * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                        grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                        grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                        grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + j] +
                                        grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                        grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)]) / 25;

                                sigma = Math.Sqrt((Math.Pow((grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2)) % curBitmap.Width] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1)) % curBitmap.Width] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + j] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[i * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[i * curBitmap.Width + j] - mu), 2) +
                                        Math.Pow((grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[i * curBitmap.Width + ((j + 2) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + j] - mu), 2) +
                                        Math.Pow((grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - mu), 2) +
                                        Math.Pow((grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - mu), 2) +
                                        Math.Pow((grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] - mu), 2)) / 25);

                                if (Math.Abs(grayValues[i * curBitmap.Width + j] - mu) < sigma * thresholding)
                                    tempArray[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j];
                                else
                                    tempArray[i * curBitmap.Width + j] = Convert.ToByte(mu);

                            }
                        }
                    }
                    grayValues = (byte[])tempArray.Clone();

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        //2018-02-05 13:39:17
        private void mask_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                mask operatorMask = new mask();
                if (operatorMask.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    int thresholding = operatorMask.GetThresholding;
                    byte flagMask = operatorMask.GetMask;
                    double[] tempArray = new double[bytes];
                    double gradX, gradY, grad;

                    switch (flagMask)
                    {
                        case 0://Roberts
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    gradX = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[i * curBitmap.Width + j];
                                    gradY = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    grad = Math.Sqrt(gradX * gradX + gradY * gradY);
                                    tempArray[i * curBitmap.Width + j] = grad;
                                }
                            }
                            break;
                        case 1://Prewitt
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    gradX = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - grayValues[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)];
                                    gradY = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    grad = Math.Sqrt(gradX * gradX + gradY * gradY);
                                    tempArray[i * curBitmap.Width + j] = grad;
                                }
                            }
                            break;
                        case 2://Sobel
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    gradX = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];
                                    gradY = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    grad = Math.Sqrt(gradX * gradX + gradY * gradY);
                                    tempArray[i * curBitmap.Width + j] = grad;
                                }
                            }
                            break;
                        case 3://Laplacian1公式(8.4)
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    grad = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - 4 * grayValues[i * curBitmap.Width + j];
                                    tempArray[i * curBitmap.Width + j] = grad;
                                }
                            }
                            break;
                        case 4://Laplacian2公式(8.5)
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    grad = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 8 * grayValues[i * curBitmap.Width + j];
                                    tempArray[i * curBitmap.Width + j] = grad;
                                }
                            }
                            break;
                        case 5://Laplacian3公式(8.6)
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    grad = -1 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        2 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 4 * grayValues[i * curBitmap.Width + j];
                                    tempArray[i * curBitmap.Width + j] = grad;
                                }
                            }
                            break;
                        case 6://Kirsch
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    grad = 0;

                                    gradX = -5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    if (gradX > grad)
                                        grad = gradX;

                                    gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    if (gradX > grad)
                                        grad = gradX;

                                    gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    if (gradX > grad)
                                        grad = gradX;

                                    gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] -
                                        5 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    if (gradX > grad)
                                        grad = gradX;

                                    gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] -
                                        5 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    if (gradX > grad)
                                        grad = gradX;

                                    gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] -
                                        5 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    if (gradX > grad)
                                        grad = gradX;

                                    gradX = -5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    if (gradX > grad)
                                        grad = gradX;

                                    gradX = -5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                        3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    if (gradX > grad)
                                        grad = gradX;

                                    tempArray[i * curBitmap.Width + j] = grad;
                                }
                            }
                            break;
                        default:
                            MessageBox.Show("无效！");
                            break;
                    }

                    if (thresholding == 0)//不进行阈值处理
                    {
                        for (int i = 0; i < bytes; i++)
                        {
                            if (tempArray[i] < 0)
                                grayValues[i] = 0;
                            else
                            {
                                if (tempArray[i] > 255)
                                    grayValues[i] = 255;
                                else
                                    grayValues[i] = Convert.ToByte(tempArray[i]);
                            }
                        }
                    }
                    else//阈值处理，生成二值边缘图像
                    {
                        if (flagMask == 3 || flagMask == 4 || flagMask == 5)
                        {
                            zerocross(ref tempArray, out grayValues, thresholding);
                        }
                        else
                        {
                            for (int i = 0; i < bytes; i++)
                            {
                                if (tempArray[i] > thresholding)
                                    grayValues[i] = 255;
                                else
                                    grayValues[i] = 0;
                            }
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void gaussian_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                gaussian8 gaussFilter = new gaussian8();
                if (gaussFilter.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    double thresholding = gaussFilter.GetThresholding;
                    double sigma = gaussFilter.GetSigma;
                    bool flag = gaussFilter.GetFlag;

                    double[] filt, tempArray;
                    createFilter(out filt, sigma, flag);
                    conv2(ref grayValues, ref filt, out tempArray);
                    zerocross(ref tempArray, out grayValues, thresholding);

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }

        }

        private void zerocross(ref double[] inputImage, out byte[] outImage, double thresh)
        {
            outImage = new byte[curBitmap.Width * curBitmap.Height];
            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {
                    if (inputImage[i * curBitmap.Width + j] < 0 && inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j] > 0 && Math.Abs(inputImage[i * curBitmap.Width + j] - inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j]) > thresh)
                    {
                        outImage[i * curBitmap.Width + j] = 255;
                    }
                    else if (inputImage[i * curBitmap.Width + j] < 0 && inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] > 0 && Math.Abs(inputImage[i * curBitmap.Width + j] - inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j]) > thresh)
                    {
                        outImage[i * curBitmap.Width + j] = 255;
                    }
                    else if (inputImage[i * curBitmap.Width + j] < 0 && inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] > 0 && Math.Abs(inputImage[i * curBitmap.Width + j] - inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)]) > thresh)
                    {
                        outImage[i * curBitmap.Width + j] = 255;
                    }
                    else if (inputImage[i * curBitmap.Width + j] < 0 && inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] > 0 && Math.Abs(inputImage[i * curBitmap.Width + j] - inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]) > thresh)
                    {
                        outImage[i * curBitmap.Width + j] = 255;
                    }
                    else if (inputImage[i * curBitmap.Width + j] == 0)
                    {
                        if (inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j] > 0 && inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] < 0 && Math.Abs(inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j]) > 2 * thresh)
                        {
                            outImage[i * curBitmap.Width + j] = 255;
                        }
                        else if (inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j] < 0 && inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] > 0 && Math.Abs(inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j]) > 2 * thresh)
                        {
                            outImage[i * curBitmap.Width + j] = 255;
                        }
                        else if (inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] > 0 && inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] < 0 && Math.Abs(inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]) > 2 * thresh)
                        {
                            outImage[i * curBitmap.Width + j] = 255;
                        }
                        else if (inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] < 0 && inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] > 0 && Math.Abs(inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]) > 2 * thresh)
                        {
                            outImage[i * curBitmap.Width + j] = 255;
                        }
                        else
                        {
                            outImage[i * curBitmap.Width + j] = 0;
                        }
                    }
                    else
                    {
                        outImage[i * curBitmap.Width + j] = 0;
                    }
                }
            }
        }

        private void createFilter(out double[] filter, double sigma, bool lod)
        {
            double std2 = 2 * sigma * sigma;
            int radius = Convert.ToInt16(Math.Ceiling(3 * sigma));
            int filterWidth = 2 * radius + 1;
            filter = new double[filterWidth * filterWidth];
            double sum = 0, average = 0;
            if (lod == false)
            {
                for (int i = 0; i < radius; i++)
                {
                    for (int j = 0; j < radius; j++)
                    {
                        int xx = (j - radius) * (j - radius);
                        int yy = (i - radius) * (i - radius);
                        filter[i * filterWidth + j] = (xx + yy - std2) * Math.Exp(-(xx + yy) / std2);
                        sum += 4 * filter[i * filterWidth + j];
                    }
                }
                for (int i = 0; i < radius; i++)
                {
                    int xx = (i - radius) * (i - radius);
                    filter[i * filterWidth + radius] = (xx - std2) * Math.Exp(-xx / std2);
                    sum += 2 * filter[i * filterWidth + radius];
                }
                for (int j = 0; j < radius; j++)
                {
                    int yy = (j - radius) * (j - radius);
                    filter[radius * filterWidth + j] = (yy - std2) * Math.Exp(-yy / std2);
                    sum += 2 * filter[radius * filterWidth + j];
                }
                filter[radius * filterWidth + radius] = -std2;
                sum += filter[radius * filterWidth + radius];
                average = sum / filter.Length;
                for (int i = 0; i < radius; i++)
                {
                    for (int j = 0; j < radius; j++)
                    {
                        filter[i * filterWidth + j] = filter[i * filterWidth + j] - average;
                        filter[filterWidth - 1 - j + i * filterWidth] = filter[i * filterWidth + j];
                        filter[filterWidth - 1 - j + (filterWidth - 1 - i) * filterWidth] = filter[i * filterWidth + j];
                        filter[j + (filterWidth - 1 - i) * filterWidth] = filter[i * filterWidth + j];
                    }
                }
                for (int i = 0; i < radius; i++)
                {
                    filter[i * filterWidth + radius] = filter[i * filterWidth + radius] - average;
                    filter[(filterWidth - 1 - i) * filterWidth + radius] = filter[i * filterWidth + radius];
                }
                for (int j = 0; j < radius; j++)
                {
                    filter[radius * filterWidth + j] = filter[radius * filterWidth + j] - average;
                    filter[radius * filterWidth + filterWidth - 1 - j] = filter[radius * filterWidth + j];

                }
                filter[radius * filterWidth + radius] = filter[radius * filterWidth + radius] - average;

            }
            else
            {
                for (int i = 0; i < radius; i++)
                {
                    for (int j = 0; j < radius; j++)
                    {
                        int xx = (j - radius) * (j - radius);
                        int yy = (i - radius) * (i - radius);
                        filter[i * filterWidth + j] = 1.6 * Math.Exp(-(xx + yy) * 1.6 * 1.6 / std2) / sigma - Math.Exp(-(xx + yy) / std2) / sigma;
                        sum += 4 * filter[i * filterWidth + j];
                    }
                }
                for (int i = 0; i < radius; i++)
                {
                    int xx = (i - radius) * (i - radius);
                    filter[i * filterWidth + radius] = 1.6 * Math.Exp(-xx * 1.6 * 1.6 / std2) / sigma - Math.Exp(-xx / std2) / sigma;
                    sum += 2 * filter[i * filterWidth + radius];
                }
                for (int j = 0; j < radius; j++)
                {
                    int yy = (j - radius) * (j - radius);
                    filter[radius * filterWidth + j] = 1.6 * Math.Exp(-yy * 1.6 * 1.6 / std2) / sigma - Math.Exp(-yy / std2) / sigma;
                    sum += 2 * filter[radius * filterWidth + j];
                }
                filter[radius * filterWidth + radius] = 1.6 / sigma - 1 / sigma;
                sum += filter[radius * filterWidth + radius];
                average = sum / filter.Length;
                for (int i = 0; i < radius; i++)
                {
                    for (int j = 0; j < radius; j++)
                    {
                        filter[i * filterWidth + j] = filter[i * filterWidth + j] - average;
                        filter[filterWidth - 1 - j + i * filterWidth] = filter[i * filterWidth + j];
                        filter[filterWidth - 1 - j + (filterWidth - 1 - i) * filterWidth] = filter[i * filterWidth + j];
                        filter[j + (filterWidth - 1 - i) * filterWidth] = filter[i * filterWidth + j];
                    }
                }
                for (int i = 0; i < radius; i++)
                {
                    filter[i * filterWidth + radius] = filter[i * filterWidth + radius] - average;
                    filter[(filterWidth - 1 - i) * filterWidth + radius] = filter[i * filterWidth + radius];
                }
                for (int j = 0; j < radius; j++)
                {
                    filter[radius * filterWidth + j] = filter[radius * filterWidth + j] - average;
                    filter[radius * filterWidth + filterWidth - 1 - j] = filter[radius * filterWidth + j];

                }
                filter[radius * filterWidth + radius] = filter[radius * filterWidth + radius] - average;
            }
        }

        private void conv2(ref byte[] inputImage, ref double[] mask, out double[] outImage)
        {
            int windWidth = Convert.ToInt16(Math.Sqrt(mask.Length));
            int radius = windWidth / 2;
            double temp;
            outImage = new double[curBitmap.Width * curBitmap.Height];

            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {
                    temp = 0;
                    for (int x = -radius; x <= radius; x++)
                    {
                        for (int y = -radius; y <= radius; y++)
                        {
                            temp += inputImage[((Math.Abs(i + x)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j + y)) % curBitmap.Width] * mask[(x + radius) * windWidth + y + radius];
                        }
                    }
                    outImage[i * curBitmap.Width + j] = temp;
                }
            }
        }

        private void canny_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                canny cannyOp = new canny();
                if (cannyOp.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte[] thresholding = new byte[2];
                    thresholding = cannyOp.GetThresh;
                    double sigma = cannyOp.GetSigma;

                    double[] tempArray;// = new double[bytes];
                    double[] tempImage = new double[bytes];
                    double[] grad = new double[bytes];
                    byte[] aLabel = new byte[bytes];
                    double[] edgeMap = new double[bytes];
                    Array.Clear(edgeMap, 0, bytes);
                    double gradX, gradY, angle;
                    int rad = Convert.ToInt16(Math.Ceiling(3 * sigma));
                    for (int i = 0; i < bytes; i++)
                        tempImage[i] = Convert.ToDouble(grayValues[i]);

                    gaussSmooth(tempImage, out tempArray, sigma);
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            gradX = tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * tempArray[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * tempArray[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];

                            gradY = tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];

                            grad[i * curBitmap.Width + j] = Math.Sqrt(gradX * gradX + gradY * gradY);

                            angle = Math.Atan2(gradY, gradX);
                            if ((angle >= -1.178097 && angle < 1.178097) || angle >= 2.748894 || angle < -2.748894)
                                aLabel[i * curBitmap.Width + j] = 0;
                            else if ((angle >= 0.392699 && angle < 1.178097) || (angle >= -2.748894 && angle < -1.963495))
                                aLabel[i * curBitmap.Width + j] = 1;
                            else if ((angle >= -1.178097 && angle < -0.392699) || (angle >= 1.963495 && angle < 2.748894))
                                aLabel[i * curBitmap.Width + j] = 2;
                            else
                                aLabel[i * curBitmap.Width + j] = 3;
                        }
                    }
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            switch (aLabel[i * curBitmap.Width + j])
                            {
                                case 3://水平方向
                                    if (grad[i * curBitmap.Width + j] > grad[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] && grad[i * curBitmap.Width + j] > grad[((i + 1) % curBitmap.Height) * curBitmap.Width + j])
                                        edgeMap[i * curBitmap.Width + j] = grad[i * curBitmap.Width + j];
                                    break;
                                case 2://正45度方向
                                    if (grad[i * curBitmap.Width + j] > grad[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] && grad[i * curBitmap.Width + j] > grad[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)])
                                        edgeMap[i * curBitmap.Width + j] = grad[i * curBitmap.Width + j];
                                    break;
                                case 1://负45度方向
                                    if (grad[i * curBitmap.Width + j] > grad[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] && grad[i * curBitmap.Width + j] > grad[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)])
                                        edgeMap[i * curBitmap.Width + j] = grad[i * curBitmap.Width + j];
                                    break;
                                case 0://垂直方向
                                    if (grad[i * curBitmap.Width + j] > grad[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] && grad[i * curBitmap.Width + j] > grad[i * curBitmap.Width + ((j + 1) % curBitmap.Width)])
                                        edgeMap[i * curBitmap.Width + j] = grad[i * curBitmap.Width + j];
                                    break;
                                default:
                                    return;
                            }
                        }
                    }

                    Array.Clear(grayValues, 0, bytes);
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            if (edgeMap[i * curBitmap.Width + j] > thresholding[0])
                            {
                                grayValues[i * curBitmap.Width + j] = 255;
                                traceEdge(i, j, edgeMap, ref grayValues, thresholding[1]);
                            }
                        }
                    }
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void traceEdge(int k, int l, double[] inputImage, ref byte[] outputImage, byte thrLow)
        {
            int[] kOffset = new int[] { 1, 1, 0, -1, -1, -1, 0, 1 };
            int[] lOffset = new int[] { 0, 1, 1, 1, 0, -1, -1, -1 };
            int kk, ll;
            for (int p = 0; p < 8; p++)
            {
                kk = k + kOffset[p];
                kk = Math.Abs(kk) % curBitmap.Height;
                ll = l + lOffset[p];
                ll = Math.Abs(ll) % curBitmap.Width;
                if (outputImage[ll * curBitmap.Width + kk] != 255)
                {
                    if (inputImage[ll * curBitmap.Width + kk] > thrLow)
                    {
                        outputImage[ll * curBitmap.Width + kk] = 255;
                        traceEdge(ll, kk, inputImage, ref outputImage, thrLow);
                    }
                }
            }
        }

        private void morph_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                morphologic8 grayMor = new morphologic8();
                if (grayMor.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte[] tempArray1 = new byte[bytes];
                    byte[] tempArray2 = new byte[bytes];
                    bool flag = grayMor.GetMethod;
                    double thresh = grayMor.GetThresh;
                    byte[] struEle = new byte[25];
                    struEle = grayMor.GetStruction;
                    int temp;

                    tempArray1 = grayDelation(grayValues, struEle, curBitmap.Height, curBitmap.Width);
                    tempArray2 = grayErode(grayValues, struEle, curBitmap.Height, curBitmap.Width);

                    for (int i = 0; i < bytes; i++)
                    {
                        if (flag == false)
                            temp = (tempArray1[i] - tempArray2[i]) / 2;
                        else
                            temp = (tempArray1[i] + tempArray2[i] - 2 * grayValues[i]) / 2;

                        if (temp > thresh)
                            grayValues[i] = 255;
                        else
                            grayValues[i] = 0;
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void wavelet8_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                wvl wavelet = new wvl();
                if (wavelet.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    double[] tempArray1 = new double[bytes];
                    double[] tempArray2 = new double[bytes];
                    double[] tempArray3 = new double[bytes];
                    double[] gradX = new double[bytes];
                    double[] gradY = new double[bytes];

                    byte multiscale = wavelet.GetScale;
                    byte[] thresholding = new byte[2];
                    thresholding = wavelet.GetThresh;

                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray1[i] = Convert.ToDouble(grayValues[i]);
                    }

                    for (int z = 0; z <= multiscale; z++)
                    {
                        double[] p = null;
                        double[] q = null;
                        switch (z)
                        {
                            case 0:
                                p = new double[] { 0.125, 0.375, 0.375, 0.125 };
                                q = new double[] { -2, 2 };
                                break;
                            case 1:
                                p = new double[] { 0.125, 0, 0.375, 0, 0.375, 0, 0.125 };
                                q = new double[] { -2, 0, 2 };
                                break;
                            case 2:
                                p = new double[] { 0.125, 0, 0, 0, 0.375, 0, 0, 0, 0.375, 0, 0, 0, 0.125 };
                                q = new double[] { -2, 0, 0, 0, 2 };
                                break;
                            case 3:
                                p = new double[] { 0.125, 0, 0, 0, 0, 0, 0, 0, 0.375, 0, 0, 0, 0, 0, 0, 0, 0.375, 0, 0, 0, 0, 0, 0, 0, 0.125 };
                                q = new double[] { -2, 0, 0, 0, 0, 0, 0, 0, 2 };
                                break;
                            default:
                                return;
                        }

                        int coff = Convert.ToInt16(Math.Pow(2, z) - 1);

                        for (int i = 0; i < curBitmap.Height; i++)
                        {
                            for (int j = 0; j < curBitmap.Width; j++)
                            {
                                double[] scl = new double[curBitmap.Width];
                                double[] wvl = new double[curBitmap.Width];
                                int temp;

                                scl[j] = 0.0;
                                wvl[j] = 0.0;
                                for (int x = -2 - 2 * coff; x < p.Length - 2 - 2 * coff; x++)
                                {
                                    temp = (Math.Abs(j + x)) % curBitmap.Width;
                                    scl[j] += p[1 + coff - x] * tempArray1[i * curBitmap.Width + temp];
                                }
                                for (int x = -1 - coff; x < q.Length - 1 - coff; x++)
                                {
                                    temp = (Math.Abs(j + x)) % curBitmap.Width;
                                    wvl[j] += q[-x] * tempArray1[i * curBitmap.Width + temp];
                                }

                                tempArray2[i * curBitmap.Width + j] = scl[j];
                                gradX[i * curBitmap.Width + j] = wvl[j];
                            }
                        }

                        for (int i = 0; i < curBitmap.Width; i++)
                        {
                            for (int j = 0; j < curBitmap.Height; j++)
                            {
                                double[] scl = new double[curBitmap.Height];
                                double[] wvl = new double[curBitmap.Height];
                                int temp;

                                scl[j] = 0.0;
                                wvl[j] = 0.0;
                                for (int x = -2 - 2 * coff; x < p.Length - 2 - 2 * coff; x++)
                                {
                                    temp = (Math.Abs(j + x)) % curBitmap.Height;
                                    scl[j] += p[1 + coff - x] * tempArray2[temp * curBitmap.Width + i];
                                }
                                for (int x = -1 - coff; x < q.Length - 1 - coff; x++)
                                {
                                    temp = (Math.Abs(j + x)) % curBitmap.Height;
                                    wvl[j] += q[-x] * tempArray1[temp * curBitmap.Width + i];
                                }

                                tempArray3[j * curBitmap.Width + i] = scl[j];
                                gradY[j * curBitmap.Width + i] = wvl[j];
                            }
                        }

                        tempArray1 = (double[])tempArray3.Clone();
                    }

                    double angle;
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            tempArray1[i * curBitmap.Width + j] = Math.Sqrt(gradX[i * curBitmap.Width + j] * gradX[i * curBitmap.Width + j] + gradY[i * curBitmap.Width + j] * gradY[i * curBitmap.Width + j]);
                            angle = Math.Atan2(gradY[i * curBitmap.Width + j], gradX[i * curBitmap.Width + j]);
                            if ((angle >= -1.178097 && angle < 1.178097) || angle >= 2.748894 || angle < -2.748894)
                                tempArray2[i * curBitmap.Width + j] = 0;
                            else if ((angle >= 0.392699 && angle < 1.178097) || (angle >= -2.748894 && angle < -1.963495))
                                tempArray2[i * curBitmap.Width + j] = 1;
                            else if ((angle >= -1.178097 && angle < -0.392699) || (angle >= 1.963495 && angle < 2.748894))
                                tempArray2[i * curBitmap.Width + j] = 2;
                            else
                                tempArray2[i * curBitmap.Width + j] = 3;
                        }
                    }


                    Array.Clear(tempArray3, 0, bytes);
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            switch (Convert.ToInt16(tempArray2[i * curBitmap.Width + j]))
                            {
                                case 3://水平方向
                                    if (tempArray1[i * curBitmap.Width + j] > tempArray1[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] && tempArray1[i * curBitmap.Width + j] > tempArray1[((i + 1) % curBitmap.Height) * curBitmap.Width + j])
                                        tempArray3[i * curBitmap.Width + j] = tempArray1[i * curBitmap.Width + j];
                                    break;
                                case 1://正45度方向
                                    if (tempArray1[i * curBitmap.Width + j] > tempArray1[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] && tempArray1[i * curBitmap.Width + j] > tempArray1[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)])
                                        tempArray3[i * curBitmap.Width + j] = tempArray1[i * curBitmap.Width + j];
                                    break;
                                case 2://负45度方向
                                    if (tempArray1[i * curBitmap.Width + j] > tempArray1[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] && tempArray1[i * curBitmap.Width + j] > tempArray1[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)])
                                        tempArray3[i * curBitmap.Width + j] = tempArray1[i * curBitmap.Width + j];
                                    break;
                                case 0://垂直方向
                                    if (tempArray1[i * curBitmap.Width + j] > tempArray1[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] && tempArray1[i * curBitmap.Width + j] > tempArray1[i * curBitmap.Width + ((j + 1) % curBitmap.Width)])
                                        tempArray3[i * curBitmap.Width + j] = tempArray1[i * curBitmap.Width + j];
                                    break;
                                default:
                                    return;
                            }
                        }
                    }

                    Array.Clear(grayValues, 0, bytes);
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            if (tempArray3[i * curBitmap.Width + j] > thresholding[0])
                            {
                                grayValues[i * curBitmap.Width + j] = 255;
                                traceEdge(i, j, tempArray3, ref grayValues, thresholding[1]);
                            }
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void pyramid_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                int series = Convert.ToInt16(Math.Log(curBitmap.Width, 2));
                glp pyramid = new glp(series);
                if (pyramid.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    double thresh = pyramid.GetThresh;
                    byte level = pyramid.GetLevel;
                    double sigma = pyramid.GetSigma;

                    double[][] pyramidImage = new double[level + 1][];
                    double[][] passImage = new double[level + 1][];
                    int levelBytes = bytes;
                    for (int k = 0; k < level + 1; k++)
                    {
                        passImage[k] = new double[levelBytes];
                        pyramidImage[k] = new double[levelBytes];
                        levelBytes = levelBytes / 4;
                    }
                    for (int i = 0; i < bytes; i++)
                        pyramidImage[0][i] = Convert.ToDouble(grayValues[i]);

                    for (int k = 0; k < level; k++)
                    {
                        double[] tempImage = null;
                        gaussSmooth(pyramidImage[k], out tempImage, sigma);
                        int coff = pyramidImage[k].Length;
                        for (int i = 0; i < coff; i++)
                        {
                            passImage[k][i] = pyramidImage[k][i] - tempImage[i];
                            int div = i / Convert.ToInt16(Math.Sqrt(coff));
                            int rem = i % Convert.ToInt16(Math.Sqrt(coff));
                            if (div % 2 == 0 && rem % 2 == 0)
                            {
                                int j = (int)((div / 2) * Math.Sqrt(pyramidImage[k + 1].Length) + rem / 2);
                                pyramidImage[k + 1][j] = tempImage[i];
                            }
                        }
                    }

                    for (int k = level - 1; k >= 0; k--)
                    {
                        int coff = pyramidImage[k].Length;
                        for (int i = 0; i < coff; i++)
                        {
                            int div = i / Convert.ToInt16(Math.Sqrt(coff));
                            int rem = i % Convert.ToInt16(Math.Sqrt(coff));
                            int j = (int)((div / 2) * Math.Sqrt(pyramidImage[k + 1].Length) + rem / 2);
                            if (div % 2 == 0 && rem % 2 == 0)
                                pyramidImage[k][i] = pyramidImage[k + 1][j];
                            else
                                pyramidImage[k][i] = 0;
                        }
                        double[] tempImage = null;
                        gaussSmooth(pyramidImage[k], out tempImage, 1);
                        for (int i = 0; i < coff; i++)
                            pyramidImage[k][i] = tempImage[i] + passImage[k][i];
                    }

                    zerocross(ref pyramidImage[0], out grayValues, thresh);

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        //2018-02-05 13:59:47
        private void hough_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                hough houghtran = new hough(curBitmap);
                houghtran.ShowDialog();
            }
        }

        private void threshold_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                thresholding thrMethod = new thresholding();
                if (thrMethod.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte method = thrMethod.GetMethod;

                    byte T = 0, S = 0;
                    byte[] neighb = new byte[bytes];
                    byte temp = 0;
                    byte maxGray = 0;
                    byte minGray = 255;
                    int[] countPixel = new int[256];
                    for (int i = 0; i < grayValues.Length; i++)
                    {
                        temp = grayValues[i];
                        countPixel[temp]++;
                        if (temp > maxGray)
                        {
                            maxGray = temp;
                        }
                        if (temp < minGray)
                        {
                            minGray = temp;
                        }
                    }
                    double mu1, mu2;
                    int numerator, denominator;
                    double sigma;
                    double tempMax = 0;
                    switch (method)
                    {
                        case 0://迭代法
                            byte oldT;
                            T = oldT = Convert.ToByte((maxGray + minGray) / 2);

                            do
                            {
                                oldT = T;
                                numerator = denominator = 0;
                                for (int i = minGray; i < T; i++)
                                {
                                    numerator += i * countPixel[i];
                                    denominator += countPixel[i];
                                }
                                mu1 = numerator / denominator;

                                numerator = denominator = 0;
                                for (int i = T; i <= maxGray; i++)
                                {
                                    numerator += i * countPixel[i];
                                    denominator += countPixel[i];
                                }
                                mu2 = numerator / denominator;

                                T = Convert.ToByte((mu1 + mu2) / 2);
                            }
                            while (T != oldT);
                            break;
                        case 1://Otsu法
                            double w1 = 0, w2 = 0;
                            double sum = 0;
                            numerator = 0;
                            for (int i = minGray; i <= maxGray; i++)
                            {
                                sum += i * countPixel[i];
                            }
                            for (int i = minGray; i < maxGray; i++)
                            {
                                w1 += countPixel[i];
                                numerator += i * countPixel[i];
                                mu1 = numerator / w1;
                                w2 = grayValues.Length - w1;
                                mu2 = (sum - numerator) / w2;
                                sigma = w1 * w2 * (mu1 - mu2) * (mu1 - mu2);

                                if (sigma > tempMax)
                                {
                                    tempMax = sigma;
                                    T = Convert.ToByte(i);
                                }
                            }
                            break;
                        case 2://一维最大熵法
                            double Ht = 0.0, Hl = 0.0, p = 0.0, pt = 0.0;
                            for (int i = minGray; i <= maxGray; i++)
                            {
                                p = (double)countPixel[i] / grayValues.Length;
                                if (p < 0.00000000000000001)
                                    continue;
                                Hl += -p * Math.Log10(p);
                            }
                            for (int i = minGray; i <= maxGray; i++)
                            {
                                p = (double)countPixel[i] / grayValues.Length;
                                pt += p;
                                if (p < 0.00000000000000001)
                                    continue;
                                Ht += -p * Math.Log10(p);
                                sigma = Math.Log10(pt * (1 - pt)) + Ht / pt + (Hl - Ht) / (1 - pt);
                                if (sigma > tempMax)
                                {
                                    tempMax = sigma;
                                    T = Convert.ToByte(i);
                                }
                            }
                            break;
                        case 3://二维最大熵

                            double[,] pap = new double[256, 256];
                            double Hl2D = 0.0, Pa = 0.0, Ha = 0.0;
                            for (int i = 0; i < bytes; i++)
                            {
                                neighb[i] = Convert.ToByte((grayValues[(i + 1) % bytes] + grayValues[Math.Abs(i - 1) % bytes] + grayValues[(i + curBitmap.Width) % bytes] + grayValues[Math.Abs(i - curBitmap.Width) % bytes]) / 4);
                            }
                            for (int i = 0; i < bytes; i++)
                            {
                                for (int j = 0; j < bytes; j++)
                                {
                                    int ii = grayValues[i];
                                    int jj = neighb[j];
                                    pap[ii, jj]++;
                                }
                            }

                            for (int i = 0; i < 256; i++)
                            {
                                for (int j = 0; j < 256; j++)
                                {
                                    pap[i, j] = ((double)pap[i, j] / bytes) / bytes;
                                    if (pap[i, j] < 0.00000000000000001)
                                        continue;
                                    Hl2D += -pap[i, j] * Math.Log10(pap[i, j]);
                                }
                            }
                            for (int i = 0; i <= 255; i++)
                            {
                                for (int j = 0; j <= 255; j++)
                                {
                                    Pa += pap[i, j];
                                    if (pap[i, j] < 0.00000000000000001)
                                        continue;
                                    Ha += -pap[i, j] * Math.Log10(pap[i, j]);
                                    sigma = Math.Log10(Pa * (1 - Pa)) + Ha / Pa + (Hl2D - Ha) / (1 - Pa);
                                    if (sigma > tempMax)
                                    {
                                        tempMax = sigma;
                                        S = Convert.ToByte(i);
                                        T = Convert.ToByte(j);
                                    }
                                }
                            }
                            break;
                        case 4://简单统计法
                            int[] ee = new int[bytes];
                            int ex, ey, ef = 0, esum = 0;
                            for (int i = 0; i < bytes; i++)
                            {
                                ex = Math.Abs(grayValues[(i + 1) % bytes] - grayValues[Math.Abs(i - 1) % bytes]);
                                ey = Math.Abs(grayValues[(i + curBitmap.Width) % bytes] - grayValues[Math.Abs(i - curBitmap.Width) % bytes]);
                                ee[i] = Math.Max(ex, ey);
                                ef += ee[i] * grayValues[i];
                                esum += ee[i];
                            }
                            T = Convert.ToByte(ef / esum);
                            break;
                        default:
                            break;
                    }

                    for (int i = 0; i < bytes; i++)
                    {
                        if (method == 3)
                        {
                            if (grayValues[i] < S && neighb[i] < T)
                                grayValues[i] = 0;
                            else
                                grayValues[i] = 255;
                        }
                        else
                        {
                            if (grayValues[i] < T)
                                grayValues[i] = 0;
                            else
                                grayValues[i] = 255;
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void clus_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                cluster cluMethod = new cluster();
                if (cluMethod.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    bool method = cluMethod.GetMethod;
                    int numbers = cluMethod.GetNumber;

                    if (method == false)//k-mean
                    {
                        int[] kNum = new int[numbers];
                        int[] kAver = new int[numbers];
                        int[] kOldAver = new int[numbers];
                        int[] kSum = new int[numbers];
                        int[] kTemp = new int[numbers];
                        byte[] segmentMap = new byte[bytes];
                        //初始化聚类均值
                        for (int i = 0; i < numbers; i++)
                        {
                            //kNum[i] = 0;
                            //kSum[i] = 0;
                            kAver[i] = kOldAver[i] = Convert.ToInt16(i * 255 / (numbers - 1));
                        }

                        while (true)
                        {
                            int order = 0;
                            for (int i = 0; i < numbers; i++)
                            {
                                kAver[i] = kOldAver[i];
                                kNum[i] = 0;
                                kSum[i] = 0;
                            }
                            //归属聚类
                            for (int i = 0; i < bytes; i++)
                            {
                                for (int j = 0; j < numbers; j++)
                                {
                                    kTemp[j] = Math.Abs(grayValues[i] - kAver[j]);
                                }
                                int temp = 255;

                                for (int j = 0; j < numbers; j++)
                                {
                                    if (kTemp[j] < temp)
                                    {
                                        temp = kTemp[j];
                                        order = j;
                                    }
                                }
                                kNum[order]++;
                                kSum[order] += grayValues[i];
                                segmentMap[i] = Convert.ToByte(order);
                            }
                            for (int i = 0; i < numbers; i++)
                            {
                                if (kNum[i] != 0)
                                    kOldAver[i] = Convert.ToInt16(kSum[i] / kNum[i]);
                            }

                            int kkk = 0;
                            for (int i = 0; i < numbers; i++)
                            {
                                if (kAver[i] == kOldAver[i])
                                    kkk++;
                            }
                            if (kkk == numbers)
                                break;
                        }

                        for (int i = 0; i < bytes; i++)
                        {
                            for (int j = 0; j < numbers; j++)
                            {
                                if (segmentMap[i] == j)
                                {
                                    grayValues[i] = Convert.ToByte(kAver[j]);
                                }
                            }
                        }
                    }
                    else//ISODATA
                    {
                        int k = 2 * numbers;
                        byte[] segmentMap = new byte[bytes];
                        List<int> kTemp = new List<int>();
                        List<int> kNum = new List<int>();
                        List<int> kAver = new List<int>();
                        List<int> kSum = new List<int>();
                        kAver.Clear();
                        kNum.Clear();
                        kTemp.Clear();
                        kSum.Clear();
                        for (int i = 0; i < k; i++)
                        {
                            kAver.Add(Convert.ToInt16(i * 255 / (k - 1)));
                            kNum.Add(0);
                            kTemp.Add(0);
                            kSum.Add(0);
                        }

                        while (true)
                        {
                            int temp;
                            for (int i = 0; i < bytes; i++)
                            {
                                kTemp.Clear();
                                int order = 0;
                                for (int j = 0; j < k; j++)
                                {
                                    kTemp.Add(Math.Abs(grayValues[i] - kAver[j]));
                                }
                                temp = 255;

                                for (int j = 0; j < k; j++)
                                {
                                    if (kTemp[j] < temp)
                                    {
                                        temp = kTemp[j];
                                        order = j;
                                    }
                                }
                                int num = kNum[order] + 1;
                                kNum.RemoveAt(order);
                                kNum.Insert(order, num);
                                int sum = kSum[order] + grayValues[i];
                                kSum.RemoveAt(order);
                                kSum.Insert(order, sum);
                                segmentMap[i] = Convert.ToByte(order);
                            }

                            for (int i = 0; i < k; i++)
                            {
                                if (kNum[i] == 0)
                                {
                                    kNum.RemoveAt(i);
                                    kAver.RemoveAt(i);
                                    kSum.RemoveAt(i);
                                    i--;
                                    k--;
                                }
                            }

                            kAver.Clear();
                            for (int i = 0; i < k; i++)
                            {
                                kAver.Add(Convert.ToInt16(kSum[i] / kNum[i]));
                            }
                            if (k <= numbers)
                                break;
                            temp = 255;
                            int removeI = 0, removeJ = 0;
                            for (int i = 0; i < k; i++)
                            {
                                for (int j = i + 1; j < k; j++)
                                {
                                    int distanceIJ = Math.Abs(kAver[i] - kAver[j]);
                                    if (distanceIJ < temp)
                                    {
                                        temp = distanceIJ;
                                        removeI = i;
                                        removeJ = j;
                                    }
                                }
                            }
                            k--;
                            kNum.Add(kNum[removeI] + kNum[removeJ]);
                            kAver.Add(Convert.ToInt16((kNum[removeI] * kAver[removeI] + kNum[removeJ] * kAver[removeJ]) / (kNum[removeI] + kNum[removeJ])));
                            kSum.Add(kNum[removeI] * kAver[removeI] + kNum[removeJ] * kAver[removeJ]);
                            kNum.RemoveAt(removeI);
                            kNum.RemoveAt(removeJ);
                            kAver.RemoveAt(removeI);
                            kAver.RemoveAt(removeJ);
                            kSum.RemoveAt(removeI);
                            kSum.RemoveAt(removeJ);
                        }

                        for (int i = 0; i < bytes; i++)
                        {
                            for (int j = 0; j < numbers; j++)
                            {
                                if (segmentMap[i] == j)
                                {
                                    grayValues[i] = Convert.ToByte(kAver[j]);
                                }
                            }
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        private void overRelax_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                ORI overRelaxIter = new ORI();
                if (overRelaxIter.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    int segNumber = overRelaxIter.GetSegNum;
                    int iterNumber = overRelaxIter.GetIterNum;

                    int[] kSum = new int[segNumber];
                    double[] kAver = new double[segNumber];
                    double[] kVar = new double[segNumber];
                    Array.Clear(kAver, 0, segNumber);
                    Array.Clear(kSum, 0, segNumber);
                    Array.Clear(kVar, 0, segNumber);

                    int[] imageMap = new int[bytes];

                    for (int i = 0; i < bytes; i++)
                    {
                        for (int j = 1; j <= segNumber; j++)
                        {
                            if (grayValues[i] < Convert.ToByte(255 * j / segNumber))
                            {
                                imageMap[i] = j - 1;
                                kAver[j - 1] += grayValues[i];
                                kSum[j - 1] += 1;
                                break;
                            }
                        }
                    }

                    for (int i = 0; i < segNumber; i++)
                    {
                        if (kSum[i] != 0)
                            kAver[i] /= kSum[i];
                    }
                    for (int i = 0; i < bytes; i++)
                    {
                        kVar[imageMap[i]] += Convert.ToInt16(Math.Pow(grayValues[i] - kAver[imageMap[i]], 2));
                    }
                    for (int i = 0; i < segNumber; i++)
                    {
                        if (kSum[i] != 0)
                            kVar[i] /= kSum[i];
                    }

                    double[] d = new double[bytes * segNumber];
                    double[] kProb = new double[bytes * segNumber];
                    Array.Clear(d, 0, bytes * segNumber);
                    Array.Clear(kProb, 0, bytes * segNumber);

                    for (int i = 0; i < bytes; i++)
                    {
                        for (int j = 0; j < segNumber; j++)
                        {
                            if (kVar[j] == 0)
                                kVar[j] = 0.00000005;
                            d[i * segNumber + j] = Math.Pow(kAver[j] - grayValues[i], 2) / kVar[j];
                            if (d[i * segNumber + j] == 0)
                                d[i * segNumber + j] = 0.00000005;
                        }
                    }

                    double tempSum = 0;
                    for (int i = 0; i < bytes; i++)
                    {
                        tempSum = 0;
                        for (int j = 0; j < segNumber; j++)
                            tempSum += 1 / d[i * segNumber + j];
                        for (int j = 0; j < segNumber; j++)
                            kProb[i * segNumber + j] = 1 / (tempSum * d[i * segNumber + j]);
                    }

                    while (iterNumber != 0)
                    {
                        iterNumber--;

                        for (int i = 0; i < bytes; i++)
                        {
                            for (int j = 0; j < segNumber; j++)
                            {
                                tempSum = kProb[(Math.Abs(i + 1 - curBitmap.Width) % bytes) * segNumber + j] + kProb[(Math.Abs(i - curBitmap.Width) % bytes) * segNumber + j] + kProb[(Math.Abs(i - 1 - curBitmap.Width) % bytes) * segNumber + j] + kProb[(Math.Abs(i - 1) % bytes) * segNumber + j] + kProb[((i - 1 + curBitmap.Width) % bytes) * segNumber + j] + kProb[((i + curBitmap.Width) % bytes) * segNumber + j] + kProb[((i + 1 + curBitmap.Width) % bytes) * segNumber + j] + kProb[((i + 1) % bytes) * segNumber + j];
                                d[i * segNumber + j] = tempSum / 8;
                                tempSum = 0;
                                for (int k = 0; k < segNumber; k++)
                                    tempSum += kProb[i * segNumber + k] * (1 + d[i * segNumber + k]);
                                kProb[i * segNumber + j] *= (1 + d[i * segNumber + j]) / tempSum;
                            }
                        }
                    }

                    for (int i = 0; i < bytes; i++)
                    {
                        double tempMax = 0;
                        int m = 0;
                        for (int j = 0; j < segNumber; j++)
                        {
                            if (kProb[i * segNumber + j] > tempMax)
                            {
                                tempMax = kProb[i * segNumber + j];
                                m = j;
                            }
                        }
                        grayValues[i] = Convert.ToByte(m * 255 / segNumber);
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                }

                Invalidate();
            }
        }

        //2018-02-05 14:06:29
        private void huffman_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                huffmanCode huffmanCoding = new huffmanCode(curBitmap);
                huffmanCoding.ShowDialog();
            }
        }

        private void shanFan_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                shannonFannon shFCoding = new shannonFannon(curBitmap);
                shFCoding.ShowDialog();
            }
        }

        private void shannon_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                shannonC shannonCoding = new shannonC(curBitmap);
                shannonCoding.ShowDialog();
            }
        }

        private void rle_Click(object sender, EventArgs e)
        {
            rleCode rleDC = new rleCode();
            if (rleDC.ShowDialog() == DialogResult.OK)
            {
                bool rleDorC = rleDC.GetDorC;
                if (rleDorC == false)
                {
                    if (curBitmap == null)
                    {
                        MessageBox.Show("请先打开图像！");
                        return;
                    }

                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                    curBitmap.UnlockBits(bmpData);

                    char[] rleData = new char[bytes * 2];
                    int rleLength = 0;
                    int position = 0;
                    char oldData, newData;
                    byte sameCount = 0;
                    char[] rleHeader = new char[6];

                    rleHeader[0] = Convert.ToChar(0x0B);
                    rleHeader[1] = Convert.ToChar(0x08);
                    rleHeader[2] = Convert.ToChar(curBitmap.Height / 0xFF);
                    rleHeader[3] = Convert.ToChar(curBitmap.Height % 0xFF);
                    rleHeader[4] = Convert.ToChar(curBitmap.Width / 0xFF);
                    rleHeader[5] = Convert.ToChar(curBitmap.Width % 0xFF);

                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        position = curBitmap.Width * i;
                        oldData = Convert.ToChar(grayValues[position]);
                        sameCount = 1;
                        for (int j = 1; j < curBitmap.Width; j++)
                        {
                            position++;
                            newData = Convert.ToChar(grayValues[position]);

                            if ((newData == oldData) && (sameCount < 63))
                                sameCount++;
                            else
                            {
                                if ((sameCount > 1) || (oldData >= 0xC0))
                                {
                                    rleData[rleLength] = Convert.ToChar(sameCount | 0xC0);
                                    rleData[rleLength + 1] = oldData;
                                    rleLength += 2;
                                }
                                else
                                {
                                    rleData[rleLength] = oldData;
                                    rleLength++;
                                }
                                oldData = newData;
                                sameCount = 1;
                            }
                        }

                        if ((sameCount > 1) || (oldData >= 0xC0))
                        {
                            rleData[rleLength] = Convert.ToChar(sameCount | 0xC0);
                            rleData[rleLength + 1] = oldData;
                            rleLength += 2;
                        }
                        else
                        {
                            rleData[rleLength] = oldData;
                            rleLength++;
                        }
                    }

                    SaveFileDialog sf = new SaveFileDialog();
                    //设置标题
                    sf.Title = "保存文件";
                    //设置文件保存类型
                    sf.Filter = "自定义图像格式(*.zrle)|*.zrle";
                    //如果用户没有输入扩展名，自动追加后缀
                    sf.AddExtension = true;
                    //如果用户单击了保存按钮
                    if (sf.ShowDialog() == DialogResult.OK)
                    {
                        //实例化一个文件流
                        FileStream fs = new FileStream(sf.FileName, FileMode.Create);
                        //实例化一个StreamWriter
                        StreamWriter sw = new StreamWriter(fs);

                        //开始写入
                        //char nc = Convert.ToChar(0xc4);
                        sw.Write(rleHeader, 0, 6);
                        sw.Write(rleData, 0, rleLength);

                        //清空缓冲区
                        sw.Flush();
                        //关闭流
                        sw.Close();
                        fs.Close();
                    }

                }
                else
                {
                    OpenFileDialog of = new OpenFileDialog();
                    //设置标题
                    of.Title = "打开文件";
                    //设置文件保存类型
                    of.Filter = "自定义图像格式(*.zrle)|*.zrle";
                    //如果用户单击了保存按钮
                    if (of.ShowDialog() == DialogResult.OK)
                    {
                        //实例化一个文件流
                        FileStream fs = new FileStream(of.FileName, FileMode.Open);
                        //实例化一个StreamReader
                        StreamReader sr = new StreamReader(fs);

                        //开始写入

                        //清空缓冲区
                        //sr.Flush();
                        int rleTemp = sr.Read();
                        if (rleTemp != 0x0B)
                        {
                            MessageBox.Show("不是zrle文件格式！");
                            sr.Close();
                            fs.Close();
                            return;
                        }
                        rleTemp = sr.Read();
                        if (rleTemp != 0x08)
                        {
                            MessageBox.Show("本实例只能处理8位灰度图像！");
                            sr.Close();
                            fs.Close();
                            return;
                        }

                        int heightRle = sr.Read();
                        rleTemp = sr.Read();
                        heightRle = heightRle * 255 + rleTemp;
                        int widthRle = sr.Read();
                        rleTemp = sr.Read();
                        widthRle = widthRle * 255 + rleTemp;

                        string rleString = sr.ReadToEnd();
                        byte[] rleData = new byte[heightRle * widthRle];

                        int count = 0;
                        int sameCount = 0;
                        int totalCount = 0;
                        char bPix;
                        for (int i = 0; i < heightRle; i++)
                        {
                            count = 0;
                            while (count < widthRle)
                            {
                                bPix = rleString[totalCount];
                                totalCount++;
                                if ((bPix & 0xC0) == 0xC0)
                                {
                                    sameCount = bPix & 0x3F;
                                    bPix = rleString[totalCount];
                                    totalCount++;
                                    for (int j = 0; j < sameCount; j++)
                                        rleData[i * widthRle + count + j] = Convert.ToByte(bPix);
                                    count += sameCount;
                                }
                                else
                                {
                                    rleData[i * widthRle + count] = Convert.ToByte(bPix);
                                    count++;
                                }
                            }
                        }

                        curBitmap = new Bitmap(widthRle, heightRle, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                        System.Drawing.Imaging.ColorPalette cp = curBitmap.Palette;
                        for (int i = 0; i < 256; i++)
                        {
                            cp.Entries[i] = Color.FromArgb(i, i, i);
                        }
                        curBitmap.Palette = cp;

                        Rectangle rectRle = new Rectangle(0, 0, widthRle, heightRle);
                        System.Drawing.Imaging.BitmapData rData = curBitmap.LockBits(rectRle, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                        IntPtr ptr = rData.Scan0;

                        System.Runtime.InteropServices.Marshal.Copy((byte[])rleData, 0, ptr, widthRle * heightRle);
                        curBitmap.UnlockBits(rData);
                        //关闭流
                        sr.Close();
                        fs.Close();
                        Invalidate();
                    }
                }
            }
        }

        private void lzw_Click(object sender, EventArgs e)
        {
            lzwCode lzwDC = new lzwCode();
            if (lzwDC.ShowDialog() == DialogResult.OK)
            {
                bool lzwDorC = lzwDC.GetDorC;
                if (lzwDorC == false)
                {
                    if (curBitmap == null)
                    {
                        MessageBox.Show("请先打开图像！");
                        return;
                    }

                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                    curBitmap.UnlockBits(bmpData);

                    ArrayList codingData = new ArrayList();
                    Hashtable codingDic = new Hashtable();

                    //初始化
                    codingData.Clear();
                    codingDic.Clear();
                    for (int i = 0; i < 256; i++)
                        codingDic.Add(i.ToString() + "|", i.ToString());
                    int valueDic = 256;

                    string prefix, suffix, fullcode;
                    string prefixIndex = null;

                    prefix = grayValues[0].ToString() + "|";
                    for (int i = 1; i < bytes; i++)
                    {
                        suffix = grayValues[i].ToString() + "|";
                        fullcode = prefix + suffix;
                        int dicLength = codingDic.Count;

                        if (codingDic.ContainsKey(fullcode))
                        {
                            prefix += suffix;
                        }
                        else
                        {
                            prefixIndex = codingDic[prefix].ToString();
                            codingData.Add(prefixIndex);
                            codingDic.Add(fullcode, valueDic.ToString());
                            valueDic++;
                            prefix = suffix;
                        }

                    }
                    prefixIndex = codingDic[prefix].ToString();
                    codingData.Add(prefixIndex);

                    SaveFileDialog sf = new SaveFileDialog();
                    //设置标题
                    sf.Title = "保存文件";
                    //设置文件保存类型
                    sf.Filter = "自定义图像格式(*.zlzw)|*.zlzw";
                    //如果用户没有输入扩展名，自动追加后缀
                    sf.AddExtension = true;
                    //如果用户单击了保存按钮
                    if (sf.ShowDialog() == DialogResult.OK)
                    {
                        //实例化一个文件流
                        FileStream fs = new FileStream(sf.FileName, FileMode.Create);
                        //实例化一个BinaryWriter
                        BinaryWriter bw = new BinaryWriter(fs);

                        //开始写入
                        int dataLength = codingData.Count;
                        bw.Write("zlzw");
                        bw.Write("8b");
                        bw.Write(curBitmap.Height.ToString());
                        bw.Write(curBitmap.Width.ToString());
                        bw.Write(dataLength.ToString());

                        for (int i = 0; i < dataLength; i++)
                            bw.Write(codingData[i].ToString());

                        //清空缓冲区
                        bw.Flush();
                        //关闭流
                        bw.Close();
                        fs.Close();
                    }
                }
                else
                {
                    OpenFileDialog of = new OpenFileDialog();
                    //设置标题
                    of.Title = "打开文件";
                    //设置文件保存类型
                    of.Filter = "自定义图像格式(*.zlzw)|*.zlzw";
                    //如果用户单击了保存按钮
                    if (of.ShowDialog() == DialogResult.OK)
                    {
                        //实例化一个文件流
                        FileStream fs = new FileStream(of.FileName, FileMode.Open);
                        //实例化一个BinaryReader
                        BinaryReader br = new BinaryReader(fs);

                        //开始写入
                        ArrayList deCodingData = new ArrayList();
                        Hashtable deCodingDic = new Hashtable();
                        deCodingData.Clear();
                        deCodingDic.Clear();
                        for (int i = 0; i < 256; i++)
                            deCodingDic.Add(i.ToString(), i.ToString() + "|");
                        int valueDic = 256;

                        string prefix = null, suffix = null, fullcode = null;
                        string readData, readOldData;

                        br.BaseStream.Position = 0;
                        readData = br.ReadString();
                        if (readData != "zlzw")
                        {
                            MessageBox.Show("不是zlzw文件格式！");
                            return;
                        }
                        readData = br.ReadString();
                        if (readData != "8b")
                        {
                            MessageBox.Show("本实例只能处理8位灰度图像！");
                            return;
                        }

                        int heightLzw, widthLzw;
                        heightLzw = Convert.ToInt32(br.ReadString());
                        widthLzw = Convert.ToInt32(br.ReadString());
                        int dataL = Convert.ToInt32(br.ReadString());

                        readData = br.ReadString();
                        deCodingData.Add(deCodingDic[readData]);
                        readOldData = readData;
                        for (int i = 1; i < dataL; i++)
                        {
                            readData = br.ReadString();
                            if (deCodingDic.ContainsKey(readData))
                            {
                                deCodingData.Add(deCodingDic[readData]);
                                prefix = deCodingDic[readOldData].ToString();
                                string tempFix = deCodingDic[readData].ToString();
                                for (int j = 0; j < tempFix.Length; j++)
                                {
                                    if (tempFix[j] == '|')
                                    {
                                        suffix = tempFix.Substring(0, j + 1);
                                        break;
                                    }
                                }
                                fullcode = prefix + suffix;
                                deCodingDic.Add(valueDic.ToString(), fullcode);
                                valueDic++;
                            }
                            else
                            {
                                prefix = deCodingDic[readOldData].ToString();
                                for (int j = 0; j < prefix.Length; j++)
                                {
                                    if (prefix[j] == '|')
                                    {
                                        suffix = prefix.Substring(0, j + 1);
                                        break;
                                    }
                                }
                                fullcode = prefix + suffix;
                                deCodingData.Add(fullcode);
                                deCodingDic.Add(valueDic.ToString(), fullcode);
                                valueDic++;
                            }
                            readOldData = readData;
                        }

                        curBitmap = new Bitmap(widthLzw, heightLzw, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                        System.Drawing.Imaging.ColorPalette cp = curBitmap.Palette;
                        for (int i = 0; i < 256; i++)
                        {
                            cp.Entries[i] = Color.FromArgb(i, i, i);
                        }
                        curBitmap.Palette = cp;

                        Rectangle rectLzw = new Rectangle(0, 0, widthLzw, heightLzw);
                        System.Drawing.Imaging.BitmapData lData = curBitmap.LockBits(rectLzw, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                        IntPtr ptr = lData.Scan0;
                        int bytesD = widthLzw * heightLzw;
                        byte[] grayLzw = new byte[bytesD];

                        int k = 0;
                        for (int i = 0; i < deCodingData.Count; i++)
                        {
                            string decodingStr = deCodingData[i].ToString();
                            int m = 0;
                            for (int j = 0; j < decodingStr.Length; j++)
                            {
                                if (decodingStr[j] == '|')
                                {
                                    int subL = j - m;
                                    grayLzw[k] = Convert.ToByte(decodingStr.Substring(m, subL));
                                    m = j + 1;
                                    k++;
                                }
                            }
                        }

                        System.Runtime.InteropServices.Marshal.Copy(grayLzw, 0, ptr, bytesD);
                        curBitmap.UnlockBits(lData);
                        //关闭流
                        br.Close();
                        fs.Close();
                        Invalidate();
                    }
                }
            }
        }

        private void dpcm_Click(object sender, EventArgs e)
        {
            dpcmCode dpcmDC = new dpcmCode();
            if (dpcmDC.ShowDialog() == DialogResult.OK)
            {
                bool dpcmDorC = dpcmDC.GetDorC;
                if (dpcmDorC == false)
                {
                    if (curBitmap == null)
                    {
                        MessageBox.Show("请先打开图像！");
                        return;
                    }

                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                    curBitmap.UnlockBits(bmpData);

                    int[] dpcmData = new int[bytes];
                    byte methodD = dpcmDC.GetMethod;
                    int tempV = 0;
                    switch (methodD)
                    {
                        case 0:
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    if (j == 0)
                                        tempV = 128;
                                    else
                                        tempV = grayValues[i * curBitmap.Width + j - 1];
                                    dpcmData[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j] - tempV;
                                }
                            }
                            break;
                        case 1:
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                if (i == 0)
                                {
                                    for (int j = 0; j < curBitmap.Width; j++)
                                    {
                                        if (j == 0)
                                            tempV = 128;
                                        else
                                            tempV = (grayValues[i * curBitmap.Width + j - 1] + 128) / 2;
                                        dpcmData[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j] - tempV;
                                    }
                                }
                                else
                                {
                                    for (int j = 0; j < curBitmap.Width; j++)
                                    {
                                        if (j == 0)
                                            tempV = (128 + grayValues[(i - 1) * curBitmap.Width + j]) / 2;
                                        else
                                            tempV = (grayValues[(i - 1) * curBitmap.Width + j] + grayValues[i * curBitmap.Width + j - 1]) / 2;
                                        dpcmData[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j] - tempV;
                                    }
                                }
                            }
                            break;
                        case 2:
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                if (i == 0)
                                {
                                    for (int j = 0; j < curBitmap.Width; j++)
                                    {
                                        if (j == 0)
                                            tempV = 64;
                                        else
                                            tempV = grayValues[i * curBitmap.Width + j - 1] + 64;
                                        dpcmData[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j] - tempV;
                                    }
                                }
                                else
                                {
                                    for (int j = 0; j < curBitmap.Width; j++)
                                    {
                                        if (j == 0)
                                            tempV = 64 + grayValues[(i - 1) * curBitmap.Width + j];
                                        else
                                            tempV = grayValues[(i - 1) * curBitmap.Width + j] + grayValues[i * curBitmap.Width + j - 1] - grayValues[(i - 1) * curBitmap.Width + j - 1];
                                        dpcmData[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j] - tempV;
                                    }
                                }
                            }
                            break;
                        case 3:
                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                if (i == 0)
                                {
                                    for (int j = 0; j < curBitmap.Width; j++)
                                    {
                                        if (j == 0)
                                            tempV = 128;
                                        else
                                            tempV = (grayValues[i * curBitmap.Width + j - 1] + 128) / 2;
                                        dpcmData[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j] - tempV;
                                    }
                                }
                                else
                                {
                                    for (int j = 0; j < curBitmap.Width; j++)
                                    {
                                        if (j == 0)
                                            tempV = (128 + grayValues[(i - 1) * curBitmap.Width + j + 1]) / 2;
                                        else if (j == curBitmap.Width - 1)
                                            tempV = (128 + grayValues[i * curBitmap.Width + j - 1]) / 2;
                                        else
                                            tempV = (grayValues[(i - 1) * curBitmap.Width + j + 1] + grayValues[i * curBitmap.Width + j - 1]) / 2;
                                        dpcmData[i * curBitmap.Width + j] = grayValues[i * curBitmap.Width + j] - tempV;
                                    }
                                }
                            }
                            break;
                        default:
                            break;
                    }
                    SaveFileDialog sf = new SaveFileDialog();
                    //设置标题
                    sf.Title = "保存文件";
                    //设置文件保存类型
                    sf.Filter = "自定义图像格式(*.zdpcm)|*.zdpcm";
                    //如果用户没有输入扩展名，自动追加后缀
                    sf.AddExtension = true;
                    //如果用户单击了保存按钮
                    if (sf.ShowDialog() == DialogResult.OK)
                    {
                        //实例化一个文件流
                        FileStream fs = new FileStream(sf.FileName, FileMode.Create);
                        //实例化一个BinaryWriter
                        BinaryWriter bw = new BinaryWriter(fs);

                        //开始写入
                        bw.Write("zdpcm");
                        bw.Write("8b");
                        bw.Write(methodD);
                        bw.Write(Convert.ToInt16(curBitmap.Height));
                        bw.Write(Convert.ToInt16(curBitmap.Width));
                        for (int i = 0; i < bytes; i++)
                            bw.Write(Convert.ToInt16(dpcmData[i]));

                        //清空缓冲区
                        bw.Flush();
                        //关闭流
                        bw.Close();
                        fs.Close();
                    }
                }
                else
                {
                    OpenFileDialog of = new OpenFileDialog();
                    //设置标题
                    of.Title = "打开文件";
                    //设置文件保存类型
                    of.Filter = "自定义图像格式(*.zdpcm)|*.zdpcm";
                    //如果用户单击了保存按钮
                    if (of.ShowDialog() == DialogResult.OK)
                    {
                        //实例化一个文件流
                        FileStream fs = new FileStream(of.FileName, FileMode.Open);
                        //实例化一个BinaryReader
                        BinaryReader br = new BinaryReader(fs);

                        br.BaseStream.Position = 0;
                        string readData = br.ReadString();
                        if (readData != "zdpcm")
                        {
                            MessageBox.Show("不是zdpcm文件格式！");
                            return;
                        }
                        readData = br.ReadString();
                        if (readData != "8b")
                        {
                            MessageBox.Show("本实例只能处理8位灰度图像！");
                            return;
                        }
                        byte methodOFDpcm = br.ReadByte();
                        int heightDpcm = br.ReadInt16();
                        int widthDpcm = br.ReadInt16();
                        int bytesD = widthDpcm * heightDpcm;
                        byte[] grayDpcm = new byte[bytesD];
                        int[] dpcmDecode = new int[bytesD];
                        for (int i = 0; i < bytesD; i++)
                        {
                            dpcmDecode[i] = br.ReadInt16();
                        }

                        int tempDV = 0;
                        switch (methodOFDpcm)
                        {
                            case 0:
                                for (int i = 0; i < heightDpcm; i++)
                                {
                                    for (int j = 0; j < widthDpcm; j++)
                                    {
                                        if (j == 0)
                                            tempDV = 128;
                                        else
                                            tempDV = grayDpcm[i * widthDpcm + j - 1];
                                        grayDpcm[i * widthDpcm + j] = (byte)(dpcmDecode[i * widthDpcm + j] + tempDV);
                                    }
                                }
                                break;
                            case 1:
                                for (int i = 0; i < heightDpcm; i++)
                                {
                                    if (i == 0)
                                    {
                                        for (int j = 0; j < widthDpcm; j++)
                                        {
                                            if (j == 0)
                                                tempDV = 128;
                                            else
                                                tempDV = (grayDpcm[i * widthDpcm + j - 1] + 128) / 2;
                                            grayDpcm[i * widthDpcm + j] = (byte)(dpcmDecode[i * widthDpcm + j] + tempDV);
                                        }
                                    }
                                    else
                                    {
                                        for (int j = 0; j < widthDpcm; j++)
                                        {
                                            if (j == 0)
                                                tempDV = (128 + grayDpcm[(i - 1) * widthDpcm + j]) / 2;
                                            else
                                                tempDV = (grayDpcm[i * widthDpcm + j - 1] + grayDpcm[(i - 1) * widthDpcm + j]) / 2;
                                            grayDpcm[i * widthDpcm + j] = (byte)(dpcmDecode[i * widthDpcm + j] + tempDV);
                                        }
                                    }
                                }
                                break;
                            case 2:
                                for (int i = 0; i < heightDpcm; i++)
                                {
                                    if (i == 0)
                                    {
                                        for (int j = 0; j < widthDpcm; j++)
                                        {
                                            if (j == 0)
                                                tempDV = 64;
                                            else
                                                tempDV = grayDpcm[i * widthDpcm + j - 1] + 64;
                                            grayDpcm[i * widthDpcm + j] = (byte)(dpcmDecode[i * widthDpcm + j] + tempDV);
                                        }
                                    }
                                    else
                                    {
                                        for (int j = 0; j < widthDpcm; j++)
                                        {
                                            if (j == 0)
                                                tempDV = 64 + grayDpcm[(i - 1) * widthDpcm + j];
                                            else
                                                tempDV = grayDpcm[i * widthDpcm + j - 1] + grayDpcm[(i - 1) * widthDpcm + j] - grayDpcm[(i - 1) * widthDpcm + j - 1];
                                            grayDpcm[i * widthDpcm + j] = (byte)(dpcmDecode[i * widthDpcm + j] + tempDV);
                                        }
                                    }
                                }
                                break;
                            case 3:
                                for (int i = 0; i < heightDpcm; i++)
                                {
                                    if (i == 0)
                                    {
                                        for (int j = 0; j < widthDpcm; j++)
                                        {
                                            if (j == 0)
                                                tempDV = 128;
                                            else
                                                tempDV = (grayDpcm[i * widthDpcm + j - 1] + 128) / 2;
                                            grayDpcm[i * widthDpcm + j] = (byte)(dpcmDecode[i * widthDpcm + j] + tempDV);
                                        }
                                    }
                                    else
                                    {
                                        for (int j = 0; j < widthDpcm; j++)
                                        {
                                            if (j == 0)
                                                tempDV = (128 + grayDpcm[(i - 1) * widthDpcm + j + 1]) / 2;
                                            else if (j == widthDpcm - 1)
                                                tempDV = (128 + grayDpcm[i * widthDpcm + j - 1]) / 2;
                                            else
                                                tempDV = (grayDpcm[i * widthDpcm + j - 1] + grayDpcm[(i - 1) * widthDpcm + j + 1]) / 2;
                                            grayDpcm[i * widthDpcm + j] = (byte)(dpcmDecode[i * widthDpcm + j] + tempDV);
                                        }
                                    }
                                }
                                break;
                            default:
                                break;
                        }

                        curBitmap = new Bitmap(widthDpcm, heightDpcm, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                        System.Drawing.Imaging.ColorPalette cp = curBitmap.Palette;
                        for (int i = 0; i < 256; i++)
                        {
                            cp.Entries[i] = Color.FromArgb(i, i, i);
                        }
                        curBitmap.Palette = cp;

                        Rectangle rectDpcm = new Rectangle(0, 0, widthDpcm, heightDpcm);
                        System.Drawing.Imaging.BitmapData dData = curBitmap.LockBits(rectDpcm, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                        IntPtr ptr = dData.Scan0;

                        System.Runtime.InteropServices.Marshal.Copy(grayDpcm, 0, ptr, bytesD);
                        curBitmap.UnlockBits(dData);
                        //关闭流
                        br.Close();
                        fs.Close();
                        Invalidate();
                    }
                }
            }
        }

        private void transform_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                transCode fftCode = new transCode();
                if (fftCode.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

                    byte sizeN = fftCode.GetSize;
                    byte ratioN = fftCode.GetRatio;

                    int sizeSI = sizeN * sizeN;
                    int col = curBitmap.Width / sizeN;
                    int row = curBitmap.Height / sizeN;
                    byte[,] splitImage = new byte[col * row, sizeSI];
                    int snum = sizeSI - sizeSI / ratioN;
                    int a, b, c, d;
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            a = j / sizeN;
                            b = j % sizeN;
                            c = i / sizeN;
                            d = i % sizeN;
                            splitImage[c * col + a, d * sizeN + b] = grayValues[i * curBitmap.Width + j];
                        }
                    }

                    Complex[] freDom = new Complex[sizeSI];
                    byte[] tempImage = new byte[sizeSI];
                    double[] temp1D = new double[sizeSI];

                    for (int i = 0; i < col * row; i++)
                    {
                        for (int j = 0; j < sizeSI; j++)
                            tempImage[j] = splitImage[i, j];
                        freDom = fft2(tempImage, sizeN, sizeN, false);
                        for (int j = 0; j < sizeSI; j++)
                            temp1D[j] = freDom[j].Abs();

                        double tempD = 0;

                        for (int m = 0; m < sizeSI - 1; m++)
                        {
                            for (int n = 0; n < sizeSI - 1 - m; n++)
                            {
                                if (temp1D[n] > temp1D[n + 1])
                                {
                                    tempD = temp1D[n];
                                    temp1D[n] = temp1D[n + 1];
                                    temp1D[n + 1] = tempD;
                                }
                            }
                        }
                        tempD = temp1D[snum - 1];
                        for (int j = 0; j < sizeSI; j++)
                        {
                            if (freDom[j].Abs() <= tempD)
                                freDom[j] = new Complex(0.0, 0.0);
                        }
                        tempImage = ifft2(freDom, sizeN, sizeN, false);
                        for (int j = 0; j < sizeSI; j++)
                            splitImage[i, j] = tempImage[j];
                    }

                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            a = j / sizeN;
                            b = j % sizeN;
                            c = i / sizeN;
                            d = i % sizeN;
                            grayValues[i * curBitmap.Width + j] = splitImage[c * col + a, d * sizeN + b];
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                    Invalidate();
                }
            }
        }


        //2018-02-05 14:32:30
        private void tranSpace_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                colorSpace clS = new colorSpace();
                if (clS.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] rgbValues = new byte[bytes * 3];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes * 3);
                    curBitmap.UnlockBits(bmpData);

                    byte colorCom = clS.GetCom;
                    byte[] grayValues = new byte[bytes];
                    byte tempB;
                    double tempD;
                    switch (colorCom)
                    {
                        case 0://red
                            for (int i = 0; i < bytes; i++)
                                grayValues[i] = rgbValues[i * 3 + 2];
                            break;
                        case 1://green
                            for (int i = 0; i < bytes; i++)
                                grayValues[i] = rgbValues[i * 3 + 1];
                            break;
                        case 2://blue;
                            for (int i = 0; i < bytes; i++)
                                grayValues[i] = rgbValues[i * 3];
                            break;
                        case 3://hue
                            double theta;
                            for (int i = 0; i < bytes; i++)
                            {
                                theta = Math.Acos(0.5 * ((rgbValues[i * 3 + 2] - rgbValues[i * 3 + 1]) + (rgbValues[i * 3 + 2] - rgbValues[i * 3])) / Math.Sqrt((rgbValues[i * 3 + 2] - rgbValues[i * 3 + 1]) * (rgbValues[i * 3 + 2] - rgbValues[i * 3 + 1]) + (rgbValues[i * 3 + 2] - rgbValues[i * 3]) * (rgbValues[i * 3 + 1] - rgbValues[i * 3]) + 0.0000000001)) / (2 * Math.PI);
                                tempD = (rgbValues[i * 3] <= rgbValues[i * 3 + 1]) ? theta : (1 - theta);
                                grayValues[i] = (byte)(tempD * 255);
                            }
                            break;
                        case 4://saturation
                            for (int i = 0; i < bytes; i++)
                            {
                                tempB = Math.Min(rgbValues[i * 3 + 2], rgbValues[i * 3 + 1]);
                                tempB = Math.Min(tempB, rgbValues[i * 3]);
                                tempD = 1.0 - 3.0 * tempB / (rgbValues[i * 3 + 2] + rgbValues[i * 3 + 1] + rgbValues[i * 3] + 0.0000000001);
                                grayValues[i] = (byte)(tempD * 255);
                            }
                            break;
                        case 5://intensity
                            for (int i = 0; i < bytes; i++)
                                grayValues[i] = (byte)((rgbValues[i * 3] + rgbValues[i * 3 + 1] + rgbValues[i * 3 + 2]) / 3);
                            break;
                        default:
                            break;
                    }

                    curBitmap = new Bitmap(curBitmap.Width, curBitmap.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                    System.Drawing.Imaging.ColorPalette cp = curBitmap.Palette;
                    for (int i = 0; i < 256; i++)
                    {
                        cp.Entries[i] = Color.FromArgb(i, i, i);
                    }
                    curBitmap.Palette = cp;
                    bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    ptr = bmpData.Scan0;
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                    Invalidate();
                }
            }
        }

        private void chCom_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                changeCom adjCom = new changeCom(this);
                adjustCom(255, 0, 0, 0);
                adjCom.Show();
            }
        }

        public void adjustCom(byte changTab, int numCom1, int numCom2, int numCom3)
        {
            Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
            System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
            IntPtr ptr = bmpData.Scan0;
            int bytes = curBitmap.Width * curBitmap.Height;
            byte[] rgbValues = new byte[bytes * 3];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes * 3);

            if (changTab == 255)
            {
                tempArray = new byte[bytes * 3];
                tempArray = (byte[])rgbValues.Clone();
                System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3);
                curBitmap.UnlockBits(bmpData);
                return;
            }


            double valueCom1 = numCom1 / 100.0;
            double valueCom2 = numCom2 / 100.0;
            double valueCom3 = numCom3 / 100.0;
            double hue, sat, inten;
            double r, g, b;
            if (changTab == 0)
            {
                for (int i = 0; i < bytes; i++)
                {
                    if (valueCom1 <= 0)
                        rgbValues[i * 3 + 2] = (byte)(tempArray[i * 3 + 2] * (1.0 + valueCom1));
                    else
                        rgbValues[i * 3 + 2] = (byte)(tempArray[i * 3 + 2] + (255.0 - tempArray[i * 3 + 2]) * valueCom1);

                    if (valueCom2 <= 0)
                        rgbValues[i * 3 + 1] = (byte)(tempArray[i * 3 + 1] * (1.0 + valueCom2));
                    else
                        rgbValues[i * 3 + 1] = (byte)(tempArray[i * 3 + 1] + (255.0 - tempArray[i * 3 + 1]) * valueCom2);

                    if (valueCom3 <= 0)
                        rgbValues[i * 3] = (byte)(tempArray[i * 3] * (1.0 + valueCom3));
                    else
                        rgbValues[i * 3] = (byte)(tempArray[i * 3] + (255.0 - tempArray[i * 3]) * valueCom3);
                }
            }
            else
            {
                valueCom1 = valueCom1 * Math.PI / 1.8;
                for (int i = 0; i < bytes; i++)
                {
                    r = tempArray[i * 3 + 2] / 255.0;
                    g = tempArray[i * 3 + 1] / 255.0;
                    b = tempArray[i * 3] / 255.0;

                    double theta = Math.Acos(0.5 * ((r - g) + (r - b)) / Math.Sqrt((r - g) * (r - g) + (r - b) * (g - b) + 0.0000001)) / (2 * Math.PI);

                    hue = (b <= g) ? theta : (1 - theta);

                    sat = 1.0 - 3.0 * Math.Min(Math.Min(r, g), b) / (r + g + b + 0.0000001);

                    inten = (r + g + b) / 3.0;

                    hue = hue * 2 * Math.PI;
                    hue = (hue + valueCom1 + 2 * Math.PI) % (2 * Math.PI);

                    if (valueCom2 <= 0)
                        sat = sat * (1.0 + valueCom2);
                    else
                        sat = sat + (1.0 - sat) * valueCom2;

                    if (valueCom3 <= 0)
                        inten = inten * (1.0 + valueCom3);
                    else
                    {
                        inten = inten + (1.0 - inten) * valueCom3;
                        if (sat == 1.0)
                            sat = sat * (1 - valueCom3);
                    }

                    if (sat == 0.0)
                        hue = 0;

                    if (hue >= 0 && hue < 2 * Math.PI / 3)
                    {
                        b = inten * (1 - sat);
                        r = inten * (1 + sat * Math.Cos(hue) / Math.Cos(Math.PI / 3 - hue));
                        g = 3 * inten - (r + b);
                    }
                    else if (hue >= 2 * Math.PI / 3 && hue < 4 * Math.PI / 3)
                    {
                        r = inten * (1 - sat);
                        g = inten * (1 + sat * Math.Cos(hue - 2 * Math.PI / 3) / Math.Cos(Math.PI - hue));
                        b = 3 * inten - (r + g);
                    }
                    else //if (h >= 4 * Math.PI / 3 && h <= 2 * Math.PI)
                    {
                        g = inten * (1 - sat);
                        b = inten * (1 + sat * Math.Cos(hue - 4 * Math.PI / 3) / Math.Cos(5 * Math.PI / 3 - hue));
                        r = 3 * inten - (g + b);
                    }
                    if (r > 1)
                        r = 1;
                    if (g > 1)
                        g = 1;
                    if (b > 1)
                        b = 1;

                    rgbValues[i * 3 + 2] = (byte)(r * 255);
                    rgbValues[i * 3 + 1] = (byte)(g * 255);
                    rgbValues[i * 3] = (byte)(b * 255);

                }
            }
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3);
            curBitmap.UnlockBits(bmpData);
            Invalidate();
        }

        private void pseudoC_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                pColor pc = new pColor();
                if (pc.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
                    curBitmap.UnlockBits(bmpData);

                    bool method = pc.GetMethod;
                    byte seg = pc.GetSeg;
                    byte[] rgbValues = new byte[bytes * 3];
                    Array.Clear(rgbValues, 0, bytes * 3);
                    byte tempB;

                    if (method == false)
                    {
                        for (int i = 0; i < bytes; i++)
                        {
                            byte ser = (byte)(256 / seg);
                            tempB = (byte)(grayValues[i] / ser);
                            rgbValues[i * 3 + 1] = (byte)(tempB * ser);
                            rgbValues[i * 3] = (byte)((seg - 1 - tempB) * ser);
                            rgbValues[i * 3 + 2] = 0;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < bytes; i++)
                        {
                            if (grayValues[i] < 64)
                            {
                                rgbValues[i * 3 + 2] = 0;
                                rgbValues[i * 3 + 1] = (byte)(4 * grayValues[i]);
                                rgbValues[i * 3] = 255;
                            }
                            else if (grayValues[i] < 128)
                            {
                                rgbValues[i * 3 + 2] = 0;
                                rgbValues[i * 3 + 1] = 255;
                                rgbValues[i * 3] = (byte)(-4 * grayValues[i] + 2 * 255);
                            }
                            else if (grayValues[i] < 192)
                            {
                                rgbValues[i * 3 + 2] = (byte)(4 * grayValues[i] - 2 * 255);
                                rgbValues[i * 3 + 1] = 255;
                                rgbValues[i * 3] = 0;
                            }
                            else
                            {
                                rgbValues[i * 3 + 2] = 255;
                                rgbValues[i * 3 + 1] = (byte)(-4 * grayValues[i] + 4 * 255);
                                rgbValues[i * 3] = 0;
                            }
                        }
                    }

                    curBitmap = new Bitmap(curBitmap.Width, curBitmap.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                    bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    ptr = bmpData.Scan0;
                    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3);
                    curBitmap.UnlockBits(bmpData);
                    Invalidate();
                }
            }
        }

        private void equC_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                eColor equC = new eColor();
                if (equC.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] rgbValues = new byte[bytes * 3];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes * 3);

                    bool method = equC.GetMethod;
                    if (method == false)
                    {
                        byte[] rValues = new byte[bytes];
                        byte[] gValues = new byte[bytes];
                        byte[] bValues = new byte[bytes];

                        for (int i = 0; i < bytes; i++)
                        {
                            rValues[i] = rgbValues[i * 3 + 2];
                            gValues[i] = rgbValues[i * 3 + 1];
                            bValues[i] = rgbValues[i * 3];
                        }

                        rValues = equalization(rValues);
                        gValues = equalization(gValues);
                        bValues = equalization(bValues);

                        for (int i = 0; i < bytes; i++)
                        {
                            rgbValues[i * 3 + 2] = rValues[i];
                            rgbValues[i * 3 + 1] = gValues[i];
                            rgbValues[i * 3] = bValues[i];
                        }
                    }
                    else
                    {
                        double[] hue = new double[bytes];
                        double[] sat = new double[bytes];
                        byte[] inten = new byte[bytes];
                        double r, g, b;

                        for (int i = 0; i < bytes; i++)
                        {
                            r = rgbValues[i * 3 + 2];
                            g = rgbValues[i * 3 + 1];
                            b = rgbValues[i * 3];

                            double theta = Math.Acos(0.5 * ((r - g) + (r - b)) / Math.Sqrt((r - g) * (r - g) + (r - b) * (g - b) + 1)) / (2 * Math.PI);

                            hue[i] = ((b <= g) ? theta : (1 - theta));

                            sat[i] = 1.0 - 3.0 * Math.Min(Math.Min(r, g), b) / (r + g + b + 1);

                            inten[i] = (byte)((r + g + b) / 3);
                        }

                        inten = equalization(inten);

                        for (int i = 0; i < bytes; i++)
                        {
                            r = rgbValues[i * 3 + 2];
                            g = rgbValues[i * 3 + 1];
                            b = rgbValues[i * 3];

                            hue[i] = hue[i] * 2 * Math.PI;
                            if (hue[i] >= 0 && hue[i] < 2 * Math.PI / 3)
                            {
                                b = inten[i] * (1 - sat[i]);
                                r = inten[i] * (1 + sat[i] * Math.Cos(hue[i]) / Math.Cos(Math.PI / 3 - hue[i]));
                                g = 3 * inten[i] - (r + b);
                            }
                            else if (hue[i] >= 2 * Math.PI / 3 && hue[i] < 4 * Math.PI / 3)
                            {
                                r = inten[i] * (1 - sat[i]);
                                g = inten[i] * (1 + sat[i] * Math.Cos(hue[i] - 2 * Math.PI / 3) / Math.Cos(Math.PI - hue[i]));
                                b = 3 * inten[i] - (r + g);
                            }
                            else //if (h >= 4 * Math.PI / 3 && h <= 2 * Math.PI)
                            {
                                g = inten[i] * (1 - sat[i]);
                                b = inten[i] * (1 + sat[i] * Math.Cos(hue[i] - 4 * Math.PI / 3) / Math.Cos(5 * Math.PI / 3 - hue[i]));
                                r = 3 * inten[i] - (g + b);
                            }
                            if (r > 255)
                                r = 255;
                            if (g > 255)
                                g = 255;
                            if (b > 255)
                                b = 255;

                            rgbValues[i * 3 + 2] = (byte)r;
                            rgbValues[i * 3 + 1] = (byte)g;
                            rgbValues[i * 3] = (byte)b;
                        }
                    }
                    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3);
                    curBitmap.UnlockBits(bmpData);
                    Invalidate();
                }
            }
        }

        private byte[] equalization(byte[] colorArray)
        {
            byte[] comValues = new byte[colorArray.Length];
            comValues = (byte[])colorArray.Clone();
            int[] countPixel = new int[256];
            byte temp;
            int[] tempArray = new int[256];
            Array.Clear(tempArray, 0, 256);
            byte[] pixelMap = new byte[256];
            for (int i = 0; i < comValues.Length; i++)
            {
                temp = comValues[i];
                countPixel[temp]++;
            }

            // 计算各灰度级的累计分布函数
            for (int i = 0; i < 256; i++)
            {
                if (i != 0)
                {
                    tempArray[i] = tempArray[i - 1] + countPixel[i];
                }
                else
                {
                    tempArray[0] = countPixel[0];
                }

                pixelMap[i] = (byte)(255.0 * tempArray[i] / comValues.Length + 0.5);
            }

            // 灰度等级映射处理
            for (int i = 0; i < comValues.Length; i++)
            {
                temp = comValues[i];
                comValues[i] = pixelMap[temp];
            }
            return comValues;
        }

        private void smoC_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                smoothColor smoothC = new smoothColor();
                if (smoothC.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] rgbValues = new byte[bytes * 3];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes * 3);

                    bool method = smoothC.GetMethod;
                    byte sideL = smoothC.GetLength;

                    if (method == false)
                    {
                        byte[] rValues = new byte[bytes];
                        byte[] gValues = new byte[bytes];
                        byte[] bValues = new byte[bytes];

                        for (int i = 0; i < bytes; i++)
                        {
                            rValues[i] = rgbValues[i * 3 + 2];
                            gValues[i] = rgbValues[i * 3 + 1];
                            bValues[i] = rgbValues[i * 3];
                        }

                        rValues = smooth11(rValues, sideL);
                        gValues = smooth11(gValues, sideL);
                        bValues = smooth11(bValues, sideL);

                        for (int i = 0; i < bytes; i++)
                        {
                            rgbValues[i * 3 + 2] = rValues[i];
                            rgbValues[i * 3 + 1] = gValues[i];
                            rgbValues[i * 3] = bValues[i];
                        }
                    }
                    else
                    {
                        double[] hue = new double[bytes];
                        double[] sat = new double[bytes];
                        byte[] inten = new byte[bytes];
                        double r, g, b;

                        for (int i = 0; i < bytes; i++)
                        {
                            r = rgbValues[i * 3 + 2];
                            g = rgbValues[i * 3 + 1];
                            b = rgbValues[i * 3];

                            double theta = Math.Acos(0.5 * ((r - g) + (r - b)) / Math.Sqrt((r - g) * (r - g) + (r - b) * (g - b) + 1)) / (2 * Math.PI);

                            hue[i] = ((b <= g) ? theta : (1 - theta));

                            sat[i] = 1.0 - 3.0 * Math.Min(Math.Min(r, g), b) / (r + g + b + 1);

                            inten[i] = (byte)((r + g + b) / 3);
                        }

                        inten = smooth11(inten, sideL);

                        for (int i = 0; i < bytes; i++)
                        {
                            r = rgbValues[i * 3 + 2];
                            g = rgbValues[i * 3 + 1];
                            b = rgbValues[i * 3];

                            hue[i] = hue[i] * 2 * Math.PI;
                            if (hue[i] >= 0 && hue[i] < 2 * Math.PI / 3)
                            {
                                b = inten[i] * (1 - sat[i]);
                                r = inten[i] * (1 + sat[i] * Math.Cos(hue[i]) / Math.Cos(Math.PI / 3 - hue[i]));
                                g = 3 * inten[i] - (r + b);
                            }
                            else if (hue[i] >= 2 * Math.PI / 3 && hue[i] < 4 * Math.PI / 3)
                            {
                                r = inten[i] * (1 - sat[i]);
                                g = inten[i] * (1 + sat[i] * Math.Cos(hue[i] - 2 * Math.PI / 3) / Math.Cos(Math.PI - hue[i]));
                                b = 3 * inten[i] - (r + g);
                            }
                            else //if (h >= 4 * Math.PI / 3 && h <= 2 * Math.PI)
                            {
                                g = inten[i] * (1 - sat[i]);
                                b = inten[i] * (1 + sat[i] * Math.Cos(hue[i] - 4 * Math.PI / 3) / Math.Cos(5 * Math.PI / 3 - hue[i]));
                                r = 3 * inten[i] - (g + b);
                            }
                            if (r > 255)
                                r = 255;
                            if (g > 255)
                                g = 255;
                            if (b > 255)
                                b = 255;

                            rgbValues[i * 3 + 2] = (byte)r;
                            rgbValues[i * 3 + 1] = (byte)g;
                            rgbValues[i * 3] = (byte)b;
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3);
                    curBitmap.UnlockBits(bmpData);
                    Invalidate();
                }
            }
        }

        private byte[] smooth11(byte[] comValues, byte sideLength)
        {
            byte halfLength = (byte)(sideLength / 2);
            byte[] comS = new byte[comValues.Length];
            comS = (byte[])comValues.Clone();
            byte[] comD = new byte[comS.Length];
            Array.Clear(comD, 0, comD.Length);
            switch (sideLength)
            {
                case 3:
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            comD[i * curBitmap.Width + j] = (byte)((comS[i * curBitmap.Width + j] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]) / 9);
                        }
                    }
                    break;
                case 5:
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            comD[i * curBitmap.Width + j] = (byte)((comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2)) % curBitmap.Width] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1)) % curBitmap.Width] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + j] +
                                            comS[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)]) / 25);
                        }
                    }
                    break;
                case 7:
                    for (int i = 0; i < curBitmap.Height; i++)
                    {
                        for (int j = 0; j < curBitmap.Width; j++)
                        {
                            comD[i * curBitmap.Width + j] = (byte)((comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2)) % curBitmap.Width] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1)) % curBitmap.Width] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + j] +
                                            comS[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 3)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            comS[i * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            comS[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            comS[((i + 2) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            comS[((Math.Abs(i - 2)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)] +
                                            comS[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                                            comS[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 2) % curBitmap.Width)] +
                                            comS[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 2) % curBitmap.Width)] +
                                            comS[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] +
                                            comS[((i + 3) % curBitmap.Height) * curBitmap.Width + j] +
                                            comS[((i + 3) % curBitmap.Height) * curBitmap.Width + ((j + 3) % curBitmap.Width)] +
                                            comS[((i + 3) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 3) % curBitmap.Width)]) / 49);
                        }
                    }
                    break;
                default:
                    break;
            }
            return comD;
        }

        private void shaC_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                sharpColor sharpC = new sharpColor();
                if (sharpC.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] rgbValues = new byte[bytes * 3];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes * 3);

                    bool method = sharpC.GetMethod;

                    if (method == false)
                    {
                        byte[] rValues = new byte[bytes];
                        byte[] gValues = new byte[bytes];
                        byte[] bValues = new byte[bytes];

                        for (int i = 0; i < bytes; i++)
                        {
                            rValues[i] = rgbValues[i * 3 + 2];
                            gValues[i] = rgbValues[i * 3 + 1];
                            bValues[i] = rgbValues[i * 3];
                        }

                        rValues = sharp(rValues);
                        gValues = sharp(gValues);
                        bValues = sharp(bValues);

                        for (int i = 0; i < bytes; i++)
                        {
                            rgbValues[i * 3 + 2] = rValues[i];
                            rgbValues[i * 3 + 1] = gValues[i];
                            rgbValues[i * 3] = bValues[i];
                        }
                    }
                    else
                    {
                        double[] hue = new double[bytes];
                        double[] sat = new double[bytes];
                        byte[] inten = new byte[bytes];
                        double r, g, b;

                        for (int i = 0; i < bytes; i++)
                        {
                            r = rgbValues[i * 3 + 2];
                            g = rgbValues[i * 3 + 1];
                            b = rgbValues[i * 3];

                            double theta = Math.Acos(0.5 * ((r - g) + (r - b)) / Math.Sqrt((r - g) * (r - g) + (r - b) * (g - b) + 1)) / (2 * Math.PI);

                            hue[i] = ((b <= g) ? theta : (1 - theta));

                            sat[i] = 1.0 - 3.0 * Math.Min(Math.Min(r, g), b) / (r + g + b + 1);

                            inten[i] = (byte)((r + g + b) / 3);
                        }

                        inten = sharp(inten);

                        for (int i = 0; i < bytes; i++)
                        {
                            r = rgbValues[i * 3 + 2];
                            g = rgbValues[i * 3 + 1];
                            b = rgbValues[i * 3];

                            hue[i] = hue[i] * 2 * Math.PI;
                            if (hue[i] >= 0 && hue[i] < 2 * Math.PI / 3)
                            {
                                b = inten[i] * (1 - sat[i]);
                                r = inten[i] * (1 + sat[i] * Math.Cos(hue[i]) / Math.Cos(Math.PI / 3 - hue[i]));
                                g = 3 * inten[i] - (r + b);
                            }
                            else if (hue[i] >= 2 * Math.PI / 3 && hue[i] < 4 * Math.PI / 3)
                            {
                                r = inten[i] * (1 - sat[i]);
                                g = inten[i] * (1 + sat[i] * Math.Cos(hue[i] - 2 * Math.PI / 3) / Math.Cos(Math.PI - hue[i]));
                                b = 3 * inten[i] - (r + g);
                            }
                            else //if (h >= 4 * Math.PI / 3 && h <= 2 * Math.PI)
                            {
                                g = inten[i] * (1 - sat[i]);
                                b = inten[i] * (1 + sat[i] * Math.Cos(hue[i] - 4 * Math.PI / 3) / Math.Cos(5 * Math.PI / 3 - hue[i]));
                                r = 3 * inten[i] - (g + b);
                            }
                            if (r > 255)
                                r = 255;
                            if (g > 255)
                                g = 255;
                            if (b > 255)
                                b = 255;

                            rgbValues[i * 3 + 2] = (byte)r;
                            rgbValues[i * 3 + 1] = (byte)g;
                            rgbValues[i * 3] = (byte)b;
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3);
                    curBitmap.UnlockBits(bmpData);
                    Invalidate();
                }
            }
        }

        private byte[] sharp(byte[] comArray)
        {
            byte[] comValues = new byte[comArray.Length];

            for (int i = 0; i < curBitmap.Height; i++)
            {
                for (int j = 0; j < curBitmap.Width; j++)
                {
                    comValues[i * curBitmap.Width + j] = (byte)(5 * comArray[i * curBitmap.Width + j] -
                        (comArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] +
                        comArray[((i + 1) % curBitmap.Height) * curBitmap.Width + j] +
                        comArray[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] +
                        comArray[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]));
                }
            }
            return comValues;
        }

        private void edgeC_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                edgeColor edgedetC = new edgeColor();
                if (edgedetC.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] rgbValues = new byte[bytes * 3];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes * 3);

                    byte method = edgedetC.GetMethod;
                    int thresh = edgedetC.GetThresholding;

                    byte[] grayValues = new byte[bytes];
                    double[] tempArray = new double[bytes];
                    byte[] rValues = new byte[bytes];
                    byte[] gValues = new byte[bytes];
                    byte[] bValues = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        rValues[i] = rgbValues[i * 3 + 2];
                        gValues[i] = rgbValues[i * 3 + 1];
                        bValues[i] = rgbValues[i * 3];
                    }
                    double maxV = 0.0;
                    double minV = 1000.0;

                    switch (method)
                    {
                        case 0:
                            double grh, ggh, gbh;
                            double grv, ggv, gbv;
                            double gxx, gyy, gxy;
                            double ge1, ge2;
                            double theta;

                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    grh = rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * rValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * rValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];
                                    ggh = gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * gValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * gValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];
                                    gbh = bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * bValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * bValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];

                                    grv = rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    ggv = gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    gbv = bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];

                                    gxx = grh * grh + ggh * ggh + gbh * gbh;
                                    gyy = grv * grv + ggv * ggv + gbv * gbv;
                                    gxy = grh * grv + ggh * ggv + gbh * gbv;

                                    theta = Math.Atan(2 * gxy / (gxx - gyy + 0.000000001)) / 2;
                                    ge1 = ((gxx + gyy) + (gxx - gyy) * Math.Cos(2 * theta) + 2 * gxy * Math.Sin(2 * theta)) / 2;
                                    theta = theta + Math.PI / 2;
                                    ge2 = ((gxx + gyy) + (gxx - gyy) * Math.Cos(2 * theta) + 2 * gxy * Math.Sin(2 * theta)) / 2;
                                    tempArray[i * curBitmap.Width + j] = Math.Max(Math.Sqrt(ge1), Math.Sqrt(ge2));

                                    if (tempArray[i * curBitmap.Width + j] > maxV)
                                        maxV = tempArray[i * curBitmap.Width + j];
                                    else if (tempArray[i * curBitmap.Width + j] < minV)
                                        minV = tempArray[i * curBitmap.Width + j];

                                }
                            }

                            for (int i = 0; i < bytes; i++)
                            {
                                grayValues[i] = (byte)((tempArray[i] - minV) * 255 / (maxV - minV));
                            }
                            break;
                        case 1:
                            double gr, gg, gb;
                            double de1, de2;

                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    gr = rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * rValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * rValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];
                                    gg = gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * gValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * gValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];
                                    gb = bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * bValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * bValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];

                                    de1 = Math.Sqrt(gr * gr + gg * gg + gb * gb);

                                    gr = rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    gg = gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    gb = bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];

                                    de2 = Math.Sqrt(gr * gr + gg * gg + gb * gb);
                                    tempArray[i * curBitmap.Width + j] = Math.Max(de1, de2);

                                    if (tempArray[i * curBitmap.Width + j] > maxV)
                                        maxV = tempArray[i * curBitmap.Width + j];
                                    else if (tempArray[i * curBitmap.Width + j] < minV)
                                        minV = tempArray[i * curBitmap.Width + j];
                                }
                            }

                            for (int i = 0; i < bytes; i++)
                            {
                                grayValues[i] = (byte)((tempArray[i] - minV) * 255 / (maxV - minV));
                            }
                            break;
                        case 2:
                            double[] rvg = new double[bytes];
                            double[] gvg = new double[bytes];
                            double[] bvg = new double[bytes];
                            double gh, gv;
                            double[] maxValue = new double[3] { 0.0, 0.0, 0.0 };
                            double[] minValue = new double[3] { 1000.0, 1000.0, 1000.0 };

                            for (int i = 0; i < curBitmap.Height; i++)
                            {
                                for (int j = 0; j < curBitmap.Width; j++)
                                {
                                    gh = rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * rValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * rValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];
                                    gv = rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + rValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - rValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    rvg[i * curBitmap.Width + j] = Math.Sqrt(gh * gh + gv * gv);
                                    if (rvg[i * curBitmap.Width + j] > maxValue[0])
                                        maxValue[0] = rvg[i * curBitmap.Width + j];
                                    else if (rvg[i * curBitmap.Width + j] < minValue[0])
                                        minValue[0] = rvg[i * curBitmap.Width + j];

                                    gh = gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * gValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * gValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];
                                    gv = gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + gValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - gValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    gvg[i * curBitmap.Width + j] = Math.Sqrt(gh * gh + gv * gv);
                                    if (gvg[i * curBitmap.Width + j] > maxValue[1])
                                        maxValue[1] = gvg[i * curBitmap.Width + j];
                                    else if (gvg[i * curBitmap.Width + j] < minValue[1])
                                        minValue[1] = gvg[i * curBitmap.Width + j];

                                    gh = bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * bValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * bValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)];
                                    gv = bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + bValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] -
                                        bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - bValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)];
                                    bvg[i * curBitmap.Width + j] = Math.Sqrt(gh * gh + gv * gv);
                                    if (bvg[i * curBitmap.Width + j] > maxValue[2])
                                        maxValue[2] = bvg[i * curBitmap.Width + j];
                                    else if (bvg[i * curBitmap.Width + j] < minValue[2])
                                        minValue[2] = rvg[i * curBitmap.Width + j];
                                }
                            }

                            for (int i = 0; i < bytes; i++)
                            {
                                rgbValues[i * 3 + 2] = (byte)((rvg[i] - minValue[0]) * 255 / (maxValue[0] - minValue[0]));
                                rgbValues[i * 3 + 1] = (byte)((gvg[i] - minValue[1]) * 255 / (maxValue[1] - minValue[1]));
                                rgbValues[i * 3] = (byte)((bvg[i] - minValue[2]) * 255 / (maxValue[2] - minValue[2]));
                                gh = Math.Max((rvg[i] - minValue[0]) * 255 / (maxValue[0] - minValue[0]), (gvg[i] - minValue[1]) * 255 / (maxValue[1] - minValue[1]));
                                gv = Math.Max(gh, (bvg[i] - minValue[2]) * 255 / (maxValue[2] - minValue[2]));
                                grayValues[i] = (byte)(gv);
                            }
                            break;
                        default:
                            break;
                    }
                    if (thresh != 0)
                    {
                        for (int i = 0; i < bytes; i++)
                        {
                            if (grayValues[i] > thresh)
                                grayValues[i] = 255;
                            else
                                grayValues[i] = 0;
                        }
                    }

                    curBitmap = new Bitmap(curBitmap.Width, curBitmap.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                    System.Drawing.Imaging.ColorPalette cp = curBitmap.Palette;
                    for (int i = 0; i < 256; i++)
                    {
                        cp.Entries[i] = Color.FromArgb(i, i, i);
                    }
                    curBitmap.Palette = cp;
                    bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    ptr = bmpData.Scan0;
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    curBitmap.UnlockBits(bmpData);
                    Invalidate();
                }
            }
        }

        private void segC_Click(object sender, EventArgs e)
        {
            if (curBitmap != null)
            {
                segColor segmentationC = new segColor();
                if (segmentationC.ShowDialog() == DialogResult.OK)
                {
                    Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = curBitmap.Width * curBitmap.Height;
                    byte[] rgbValues = new byte[bytes * 3];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes * 3);

                    byte numbers = segmentationC.GetNum;

                    int[] kNum = new int[numbers];
                    int[] kAver = new int[numbers * 3];
                    int[] kOldAver = new int[numbers * 3];
                    int[] kSum = new int[numbers * 3];
                    double[] kTemp = new double[numbers];
                    byte[] segmentMap = new byte[bytes * 3];
                    //初始化聚类均值
                    for (int i = 0; i < numbers; i++)
                    {

                        kAver[i * 3 + 2] = kOldAver[i * 3 + 2] = Convert.ToInt16(i * 255 / (numbers - 1));
                        kAver[i * 3 + 1] = kOldAver[i * 3 + 1] = Convert.ToInt16(i * 255 / (numbers - 1));
                        kAver[i * 3] = kOldAver[i * 3] = Convert.ToInt16(i * 255 / (numbers - 1));
                    }
                    int count = 0;
                    while (true)
                    {
                        int order = 0;
                        for (int i = 0; i < numbers; i++)
                        {
                            kNum[i] = 0;
                            kSum[i * 3 + 2] = kSum[i * 3 + 1] = kSum[i * 3] = 0;
                            kAver[i * 3 + 2] = kOldAver[i * 3 + 2];
                            kAver[i * 3 + 1] = kOldAver[i * 3 + 1];
                            kAver[i * 3] = kOldAver[i * 3];
                        }
                        //归属聚类
                        for (int i = 0; i < bytes; i++)
                        {
                            for (int j = 0; j < numbers; j++)
                            {
                                kTemp[j] = Math.Pow(rgbValues[i * 3 + 2] - kAver[j * 3 + 2], 2) + Math.Pow(rgbValues[i * 3 + 1] - kAver[j * 3 + 1], 2) + Math.Pow(rgbValues[i * 3] - kAver[j * 3], 2);
                            }
                            double temp = 100000;

                            for (int j = 0; j < numbers; j++)
                            {
                                if (kTemp[j] < temp)
                                {
                                    temp = kTemp[j];
                                    order = j;
                                }
                            }
                            kNum[order]++;
                            kSum[order * 3 + 2] += rgbValues[i * 3 + 2];
                            kSum[order * 3 + 1] += rgbValues[i * 3 + 1];
                            kSum[order * 3] += rgbValues[i * 3];
                            segmentMap[i] = Convert.ToByte(order);
                        }
                        for (int i = 0; i < numbers; i++)
                        {
                            if (kNum[i] != 0)
                            {
                                kOldAver[i * 3 + 2] = Convert.ToInt16(kSum[i * 3 + 2] / kNum[i]);
                                kOldAver[i * 3 + 1] = Convert.ToInt16(kSum[i * 3 + 1] / kNum[i]);
                                kOldAver[i * 3] = Convert.ToInt16(kSum[i * 3] / kNum[i]);
                            }
                        }

                        int kkk = 0;
                        count++;
                        for (int i = 0; i < numbers; i++)
                        {
                            if (kAver[i * 3 + 2] == kOldAver[i * 3 + 2] && kAver[i * 3 + 1] == kOldAver[i * 3 + 1] && kAver[i * 3] == kOldAver[i * 3])
                                kkk++;
                        }
                        if (kkk == numbers || count == 100)
                            break;
                    }

                    for (int i = 0; i < bytes; i++)
                    {
                        for (int j = 0; j < numbers; j++)
                        {
                            if (segmentMap[i] == j)
                            {
                                rgbValues[i * 3 + 2] = Convert.ToByte(kAver[j * 3 + 2]);
                                rgbValues[i * 3 + 1] = Convert.ToByte(kAver[j * 3 + 1]);
                                rgbValues[i * 3] = Convert.ToByte(kAver[j * 3]);
                            }
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes * 3);
                    curBitmap.UnlockBits(bmpData);
                    Invalidate();
                }
            }
        }
    }
}
